迭代器和可迭代协议
admin
2023-07-06 23:59:58
0

可迭代对象包括实际序列和按照需求计算的虚拟序列

#手动迭代:iter和next

#python3.0提供了一个内置函数next,它会自动调用一个对象的next方法,给定一个
#可迭代对象x。调用next(x)等同于x,next()

列表以及其他对象不是自身的迭代器,他们可以调用iter来启动迭代

l = [1, 2, 3]
print(iter(l) is l)

False

#print(l.next())

AttributeError: 'list' object has no attribute 'next'

l = [1, 2, 3]
i = iter(l)
print(next(i))

1

print(i.next())

2

l = [1, 2, 3]
for x in l:
print(x**2, end=' ')

1 4 9

l = [1, 2, 3]
i = iter(l)
while True:
try:
j = next(i)
except StopIteration:
break
else:
print(j ** 2, end=' ')

1 4 9

python2 中迭代方法是x.next, python3是x.next,但next函数确是都可用的。

其他迭代器

d = {'a':1, 'b':2, 'c':3}
for k in d.keys():
print(k, d[k])

a 1

b 2

c 3

#python3中,字典自己有个迭代器
i = iter(d)
print(next(i))
print(next(i))
print(next(i))

a

b

c

因此我们不需要调用keys方法来遍历字典,for将使用迭代协议获取键。

for k in d:
print(k, d[k])

a 1

b 2

c 3

shelves和os.popen的结果也是可迭代的

import os
p = os.popen('dir')
print(p.next())

驱动器 F 中的卷没有标签。

注意py2中popen对象支持p.next方法,py3中支持p.next()方法。

#迭代协议也是需要将结果包装到一个list中才能看到值。可迭代对象一次返回一

个结果,而不是一个列表

a = range(5)
print(a)

range(0, 5)

i = iter(a)
print(next(i))
print(next(i))

0

1

print(list(range(5)))

[0, 1, 2, 3, 4]

列表解析

l = []
for i in [1, 2, 3]:
l.append(i+1)
print(l)

[2, 3, 4]

相比普通的循环,列表解析也可以达到相同的目的,并且更加简洁,运行速度也比

普通的循环快

print([i+1 for i in [1, 2, 3]])

[2, 3, 4]

文件中的列表解析

with open('some.py', 'w') as f:
f.write('import os\n')
f.write('a = 1\n')
f.write('b = 2\n')
with open('some.py') as f:
print(f.read())

import os

a = 1

b = 2

f = open('some.py')
line = f.readlines()
print(line)

['import os\n', 'a = 1\n', 'b = 2\n']

如果要去掉行末的换行符的话。

print([l.rstrip() for l in line])

['import os', 'a = 1', 'b = 2']

因为列表解析像for循环语句是一个迭代环境, 我们甚至不用提前打开文件。

l = [line.rstrip() for line in open('some.py')]
print(l)

['import os', 'a = 1', 'b = 2']

除此之外。列表解析的表现力也很强,我们可以在迭代时在一个文件上运行任何的

#字符串操作
print([line.upper() for line in open('some.py')])

['IMPORT OS\n', 'A = 1\n', 'B = 2\n']

列表解析也可以嵌套for循环和if

lines = [line.rstrip() for line in open('some.py') if line[0] == 'a']
print(lines)

['a = 1']

print([x+y for x in 'abc' for y in 'lmn'])

['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']

#列表解析,in成员测试,map内置函数,sorted和zip都使用了迭代协议
#当应用文件时,会自动扫描

upper = [line.upper() for line in open('some.py')]
print(upper)

['IMPORT OS\n', 'A = 1\n', 'B = 2\n']

print(list(map(str.upper, open('some.py'))))

['IMPORT OS\n', 'A = 1\n', 'B = 2\n']

print('a = 1\n' in open('some.py'))

True

print(sorted(open('some.py')))

['a = 1\n', 'b = 2\n', 'import os\n']

print(list(zip(open('some.py'), open('some.py'))))

[('import os\n', 'import os\n'), ('a = 1\n', 'a = 1\n'), ('b = 2\n', 'b = 2\n')]

print(list(enumerate(open('some.py'))))

[(0, 'import os\n'), (1, 'a = 1\n'), (2, 'b = 2\n')]

print(list(filter(bool, open('some.py'))))

['import os\n', 'a = 1\n', 'b = 2\n']

import functools, operator
print(functools.reduce(operator.add, open('some.py')))

import os

a = 1

b = 2

print(sum([1, 2, 3, 4, 5]))

15

print(any(['spam', '', 'mi']))

True

print(all(['spam', '', 'mi']))

False

print(max([1, 2, 3, 4, 5]))

5

print(min([1, 2, 3, 4, 5]))

1

max 和min 也可以应用于文件

print(max(open('some.py')))

import os

print(min(open('some.py')))

a = 1

迭代协议也可直接作用于文件

print(list(open('some.py')))

['import os\n', 'a = 1\n', 'b = 2\n']

print(tuple(open('some.py')))

('import os\n', 'a = 1\n', 'b = 2\n')

print('&&'.join(open('some.py')))# (牛逼)
#import os
#&&a = 1
#&&b = 2

a, *b = open('some.py')
print(a)
print(b)
#import os
#
#['a = 1\n', 'b = 2\n']

解析和集合

print(set(open('some.py')))

{'b = 2\n', 'a = 1\n', 'import os\n'}

print({line for line in open('some.py')})

{'a = 1\n', 'b = 2\n', 'import os\n'}

print({ix: line for ix, line in enumerate(open('some.py'))})

{0: 'import os\n', 1: 'a = 1\n', 2: 'b = 2\n'}

print({line for line in open('some.py') if line[0] == 'a'})

{'a = 1\n'}

print({ix: line for ix, line in enumerate(open('some.py')) if line[0] == 'a'})

{1: 'a = 1\n'}

def f(a, b, c):
print(a, b, c, sep = '&')

f(1, 2, 3)

1-2-3

f(*open('some.py'))

import os

&a = 1

&b = 2

x , y = (1, 2), (3, 4)
print(list(zip(x, y)))

[(1, 3), (2, 4)]

a, b = zip(*zip(x, y))
print(a)
print(b)

(1, 2)

(3, 4)

range和其他迭代器不同,rang它不是自己的迭代器,并且他支持在结果上的多个迭代器

他们会记住自己的位置

r = range(3)
i1 = iter(r)
print(next(i1))

0

print(next(i1))

1

i2 = iter(r)
print(next(i2))

0

print(next(i1))

2

而zip,map,filter不支持相同结果上的活跃迭代器

z = zip((1, 2, 3), (10, 11, 12))
i1 = iter(z)
i2 = iter(z)
print(next(i1))

(1, 10)

print(next(i1))

(2, 11)

print(next(i2))

(3, 12)

m = map(abs,(-1, 0, 1))
i1 = iter(m)
i2 = iter(m)
print(next(i1)) # 1
print(next(i1)) # 0
print(next(i1)) # 1
#print(next(i2)) # StopIteration

r = range(3)
r1, r2 = iter(r), iter(r)
print(next(r1)) # 0
print(next(r1)) # 1
print(next(r1)) # 2
print(next(r2)) # 0

通过iter返回一个新的对象来支持多个迭代器,单个迭代器返回自身。

py3中字典中由于keys不在返回一个列表,所以应该首先用list来展示他

或者使用sorted

d = {'a':1, 'b':2, 'c':3}
for k in sorted(d.keys()):
print(k, d[k], end=' ')

a 1 b 2 c 3

for k in sorted(d):
print(k, d[k], end = ' ')

a 1 b 2 c 3

相关内容

热门资讯

我国科学家为细胞信号“导航”开... 新华社济南5月31日电(记者张力元)人体细胞犹如一座精密的通信城市,每天都有大量“指令”穿梭传递,调...
极端大风突袭哈尔滨!过山车停摆... 极目新闻记者 詹钘5月31日,受强对流天气影响,哈尔滨国际会展中心体育场相关设施受到损坏,原计划当晚...
三原电缆取得电缆接头连接用防护... 国家知识产权局信息显示,上海三原电缆附件有限公司取得一项名为“一种电缆接头连接用防护结构”的专利,授...
原创 识... 还是那句话,机圈苦大屏久已…… 虽然大屏有大屏的美,但是小屏也有小屏的俏。在大屏旗舰占据主流的手机市...
玄戒技术取得分频电路专利,实现... 国家知识产权局信息显示,北京玄戒技术有限公司取得一项名为“分频电路、分频器、射频芯片和电子设备”的专...
为什么今年香会基调明显变了 5月29日—31日在新加坡举行的第23届香格里拉对话会(简称“香会”),见证着元首引领下大国关系继续...
成本几毛钱、假驱蚊液香精兑水,... 入夏升温,蚊虫进入活跃期,驱蚊防护成为民生刚需,《财经调查》持续接到消费者投诉,他们买到的多款网红驱...
越来越多80后90后,正在丧失... 六一儿童节到来之际,朋友圈里开始出现一种熟悉的热闹。有人晒出零食礼包,有人半开玩笑地向伴侣讨礼物,还...
洋保电子取得用于低温环境的电气... 国家知识产权局信息显示,洋保电子(太仓)有限公司取得一项名为“一种用于低温环境的电气柜”的专利,授权...
中日韩飞手争霸宁波!2026无... 潮新闻客户端 记者 陈冲 通讯员 朱凝 5月31日,2026小遛·无人机竞速世界杯(中国·宁波鄞州站...