问题引入:
对一个列表里所有数值求平方;
lst = list(range(10))
之所以叫列表解析是因为得到的结果是list,迭代的对象可以是任意可迭代对象;
列表解析中,不支持break语句,自然也不支持for...else语句;
[ expression for e in iterator]
lst = list(range(10))
ret = []
for x in lst:
ret.append(x ** 2)
ret = [ x ** 2 for x in lst]- 代码简介,可读性强;
- 效率比普通迭代稍高;
[expression for e in iterator if condision]lst = list(range(10))
ret = list()
In [9]: %%timeit
...: for x in lst:
...: if x % 2 == 0:
...: ret.append(x)
...:
1000000 loops, best of 3: 1.67 µs per loop
In [11]: %%timeit
...: [ ret.append(x) for x in lst if x % 2 == 0]
...:
100000 loops, best of 3: 2.33 µs per loop-
带多个if
- 多个if间默认为and关系;
ret = [ x for x in lst if x > 0 if x < 5 if x % 2 == 0]
ret = []
for x in lst:
if x > 0:
if x < 5:
if x % 2 == 0:
ret.append(x)- 多个if语句的,都可以转换为条件的逻辑运算,所以一般来说,不会带多个if语句;
- 也可以带多个for语句:
[(x,y) for x in range(5) for y in range(5,10)]
相当于逐层嵌套;
ret = []
for x in range(5):
for y in range(5,10):
ret.append((x,y))多个for语句,也可跟多个if语句;
[(x,y) for x in range(5) if x > 0 for y in range(5,10) if y < 9]使用列表解析的目的是为了让代码更简洁。
[x for x in [y for y in range(10)]]跟着感觉走,如果解析式不能让代码更简洁的情况下,就不要再使用了;
一眼看不出解析式的结果是什么的时候,就不要用了;
问题引入:
偶数求平方,奇数求立方;
x if cond else y
当条件满足时返回x,当条件不满足时返回y;
使用该表达式与列表解析式结合使用:
[x ** 2 if x % 2 == 0 else x ** 3 for x in lst]
ret = []
for x in lst:
if x % 2 == 0:
ret.append(x ** 2)
else:
ret.append(x ** 3)x = 3
x ** 2 if x % 2 == 0 else x ** 3
ret = 0
if x % 2 == 0:
ret = x ** 2
else:
ret = x ** 3列表解析返回的是列表;
range(10000000) 并非马上生成了所有元素;
列表解析是马上生成了所有元素;
(x ** 2 for x in range(10000))
列表解析的中括号变成小括号;
生成器解析式返回的是一个生成器;
g = (x ** 2 for x in range(100000000000))生成器只有在取值的时候才开始计算;
需要用下标访问的时候,用列表解析;
只需要对结果迭代的时候,优先使用生成器解析;
{x for x in range(10)}
s = { x for x in range(10)}
操作和列表解析式一样的;
{ str(key): v for key in range(10) for v in range(11,20)}
可迭代对象:
r = range(5)
r.__iter__()
可迭代对象,都拥有__iter__()方法;
for x in range(5): pass
for in 语句要求遍历一个可迭代对象;
可迭代对象:
7种数据结构;
range
dict.keys
dict.items
dict.values
it = iter(range(5))
有__next__方法的可迭代对象叫迭代器;
上述可迭代对象中,没有迭代器;
可迭代对象可以转换为迭代器
iter()函数可以把一个可迭代对象转换为迭代器;
为什么要转换?
next函数可以从迭代器中取出下一个元素;
迭代器会保存一个指针,指向可迭代对象的当前元素;
调用next函数的时候,会返回当前元素,并且把指针指向下一个元素;
当没有下一个元素时,会抛出StopIteration异常;
for in循环可迭代对象; 首先调用iter方法转换为迭代器,然后不断的调用next方法,知道抛出StopIteration异常
# 迭代器的实现:
it = iter(iteratable):
while True:
try:
next(it)
except StopIteration:
return