列表生成式
在C语音中,列表的生成一般使用for循环来实现,但在Python中生成一个列表式十分简单的,简单的顺序列表可以通过range
函数生成,
>>> list(range(1,10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
但是对于有一定规律的列表,一般都是使用for循环来依次生成,在Python中通过列表生产式可以直接生成复杂的列表。
>>> [x*x*x for x in range(1, 10)]
[1, 8, 27, 64, 125, 216, 343, 512, 729]
还可以进一步增加约束来产生更复杂的序列
>>> [x*x*x for x in range(1, 10) if x % 3 == 0]
[27, 216, 729]
也可以使用多层循环实现多层遍历或组合
>>> [x + y for x in '1234' for y in '1234' if x != y]
['12', '13', '14', '21', '23', '24', '31', '32', '34', '41', '42', '43']
列表生成器的逻辑与其对应的语句是一致的,如上所示,for x in '1234' for y in '1234'
是循环的范围,这里可以通过多个for
实现多层循环的嵌套,x+y
等于循环中执行的语句,if x != y
是最终语句执行的约束条件。遵循这一逻辑,列表生成器可以生成多种不同的list,只要是按照标准for循环可以实现的list,基本都可以使用列表生成器实现。
>>> a="This Is A Test"
>>> [s.lower() for s in a]
['t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't']
生成器
虽然列表生成式可以直接创建一个我们想要的列表,但是注意到一点,在创建时需要列表的大小是制定的,就是说需要分配一块指定大小的内存来保存结果。同时在一些情况下,对于具有指定规律的list,我们不需要一个完整的list,只需要在使用时可以获取对应位置的值即可。因此在Python中,这种一边循环一边计算,不需要完全创建一个list的方法就叫做生成器,generator。和列表生辰式的使用方法基本一直,只是使用()来代替[],返回的结果也不是list,而是generator。
>>> g = (x+y for x in range(5) for y in range(5) if x != y)
>>> g
<generator object <genexpr> at 0x7f96a68ae410>
generator也是一个可迭代的数据类型,可以使用for
循环取出对应的值,而且不用担心出现StopIteration
的错误出现。
generator是一个强大的工具,不光能直接在表达式中使用,在函数中也可以使用,来生成更加复杂的有序集合,在函数中通过yield
来将需要的元素输出的generator
中,如下的例子中生成所有奇数的generator。
def odd():
n = 1
while True:
n = n + 2
yield n
迭代
在Python中,for循环是使用for...in
来完成的,这是一种抽象的for循环遍历,这种遍历被称为迭代(Iteration).
对于dict的迭代,for key in dict:
是对key的迭代,使用for value in d.value()
来迭代value,使用for k,v in d.items()
来同时迭代key和value。
对于字符串,也可以使用迭代依次取出每个字符。
如果要知道对象是不是可迭代的(Iterable),需要使用导入collections模块的Iterable类型判断,isinstance([1,2,3], Iterable)
.
在对list进行迭代时,如果还需要知道对象的下标,则需要使用enumerate
函数,如for i, v in enumerate(['one', 'two', 'three'])
.
对于元素是tuple或list的list,可以直接在迭代是使用多个参数取值,
for x,y in [(1,1), (2,2)]:
print(x,y)
迭代器
一般可以用于for
循环的数据类型,都是可迭代的数据类型,即Iterable
,但他们不是迭代器Iterator
,如list
、tuple
都是Iterable
,而generator
都是Iterator
。因为迭代器对象指的是一个数据流,它可以通过next
一致取出下一个值,直到StopInteration
的异常抛出,所以可以将迭代器看做是一个有序的序列,但是我们不知道序列的大小,在使用next
取出元素之前,也不能直接得到指定的元素,所以迭代器是惰性
的,它可以指代无限大的序列,如全体整数、自然数或奇数,而list和tuple是有指定大小的数据流,需要在内存中分配指定大小的内存块。