列表推导式
[表达式 for 局部变量名 in 可迭代对象]
[表达式 for 局部变量名 in 可迭代对象 if 条件]
如:
print([i**2 for i in range(1,10)])
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 生成1~9的平方存储进列表后打印此列表
print([i**2 for i in range(1,10) if i>5])
# [36, 49, 64, 81]
# 生成1~9的平方,如果i大于5,则存储进列表,然后打印此列表
# (即生成6~9的平方存储进列表后打印此列表)
字典推导式
{键:值 for 局部变量名 in 可迭代对象 }
{键:值 for 局部变量名 in 可迭代对象 if 条件 }
如:
print({i:i**2 for i in range(1,10)})
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
# 生成1~9对应1~9平方的键值对存储进字典后打印此列表
print([i**2 for i in range(1,10) if i>5])
# {6: 36, 7: 49, 8: 64, 9: 81}
# 生成1~9对应1~9平方的键值对,如果i大于5,则存储进字典,然后打印此字典
# (即生成6~9对应6~9平方的键值对存储进字典后打印此字典)
集合推导式
{表达式 for 局部变量名 in 可迭代对象}
{表达式 for 局部变量名 in 可迭代对象 if 条件}
如:
print({i**2 for i in range(1,10)})
# {64, 1, 4, 36, 9, 16, 49, 81, 25}
# 生成1~9的平方存储进集合后打印此集合
print({i**2 for i in range(1,10) if i>5})
# {64, 49, 36, 81}
# 生成1~9的平方,如果i大于5,则存储进集合,然后打印此集合
# (即生成6~9的集合存储进集合后打印此集合)
元组推导式
元组推导式和另外三种推导式有一点点不同。。。由于其返回生成器对象,所以它也叫生成器表达式(迭代器的优势:相比较于列表推导式等更节约资源)。但我们可以用tuple(或list、set等)让它成为一个名副其实的“元组推导式”:
t = (i for i in range(3))
# 普通元组推导式
t = tuple(t)
#真·“元组推导式”
(表达式 for 局部变量名 in 可迭代对象)
(表达式 for 局部变量名 in 可迭代对象 if 条件)
如:
for j in (i**2 for i in range(1,10)):
print(j, end=' ')
# 1 4 9 16 25 36 49 64 81
# 生成1~9的平方存储进生成器对象后遍历打印
for j in (i**2 for i in range(1,10) if i>5):
print(j, end=' ')
# 36 49 64 81
# 生成1~9的平方,如果i大于5,则存储进生成器对象,然后遍历打印
# (即生成6~9的平方存储进生成器对象后遍历打印)
推导式与双分支结构紧凑格式
我们可以将双分支结构的if-else紧凑格式与推导式搭配使用,以搭配列表推导式为例:
[表达式1 if 条件 else 表达式2 for 局部变量名 in 可迭代对象]
print([i**2 if i!=9 else 0 for i in range(1,10)])
# 生成1~9的平方存储进列表,如果i不是9,则正常存储进列表
# 如果此时i是9,则将当前i替换成0存储进列表,然后打印此列表
print([i**2 if i!=9 else 0 for i in range(1,10) if i>5])
# [36, 49, 64, 0]
# 生成1~9的平方存储进列表,如果i大于5且i不是9,则正常存储进列表
# 如果此时i是9,则将当前i替换成0存储进列表,然后打印此列表
# (即生成6~9的平方存储进列表,再把i=9时的结果81替换成0后打印此列表)
迭代器
- 迭代器协议是指实现了__next__魔法方法的类。
- 只要是遵循迭代器协议并实现__iter__魔法方法的对象都可以称作“可迭代对象”。
- Python部分关键词(如for等)和内建函数(如sum等)都遵循迭代器协议。
- 迭代器在无可迭代对象后会触发StopIteration异常。
- 我们也可以通过调用内建函数
iter()
来创建迭代器,其实质是调用其类或对象的__iter__方法。 - 迭代器相对普通类型更省内存。
- 迭代器只能向后迭代,不能向前迭代。
如下,我们可以制作一个调用计数器:
class MyClass():
counter = 0
def __iter__(self):
print('调用了__iter__方法!')
return self
def __next__(self):
print('调用了__next__方法!')
self.counter += 1
my_class_obj = MyClass()
next(my_class_obj)
next(my_class_obj)
next(my_class_obj)
next(my_class_obj)
print(my_class_obj.counter)
它的结果是:
调用了__next__方法!
调用了__next__方法!
调用了__next__方法!
调用了__next__方法!
4
生成器
生成器是使用yield关键词的函数。每一个生成器都是迭代器,但迭代器不一定是生成器。可以说,生成器是简化了的迭代器。
yield与return相似,但与return不同的一点是,函数会在下一次使用next函数的时候返回下一个yield结果,直到触发StopIteration异常,如:
def func():
yield 1
yield 2
f = func()
print(next(f))
print(next(f))
print(next(f))
其结果是:
1
2
Traceback (most recent call last):
File "*", line *, in *
print(next(f))
StopIteration
由上,我们可以创建一个上限为10的计数器:
def func():
counter = 0
for i in range(10):
counter += 1
yield counter
只要next方法调用次数不超过10,就不会触发StopIteration异常。
实际yield还有一种派生用法:yield from 可迭代对象
,会每次自动返回其遍历可迭代对象的当前值,如下两个函数的用法是完全相同的:
def func1():
for i in range(5):
yield i
def func2():
yield from range(5)
标签:__,迭代,Python,生成器,next,range,print,列表
From: https://www.cnblogs.com/XuShuo-Self/p/17253585.html