python标准库学习(二)

可迭代对象与迭代器

可迭代对象与迭代器概念不同。可迭代对象在内部实现了__iter__,所以可以进行迭代,迭代器在内部实现了__iter____next__,所以是个迭代器也可以进行迭代。

举例:

1
2
3
4
>>> mylist = [x for x in range(10)]
#mylist是个列表,可以进行迭代
>>> mylist = (x for x in range(10)) #生成器表达式,结果同iter(mylist)
#现在mylist是个迭代器,可以使用.next()方法

生成器

生成器本质就是一个迭代器,自带了iter方法和next方法。迭代器是用来迭代可迭代对象的,而生成器是用来迭代方法的。调用函数的之后函数不执行,返回一个生成器每次调用next方法的时候会取到一个值直到取完最后一个,再执行next会报错。

生成器表达式类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表。

比较:

  • 列表表达式在生成后可以按序列取值,排序,切片等,但是占用内存大。
  • 生成器表达式只是产生一个可迭代对象,需要时再迭代取值,占用内存小,但是不可进行列表的操作,迭代完后对象清空。

itertools

itertools.product

产生多个列表和迭代器的笛卡尔积,可以用product来改写深度嵌套的列表推导操作。

1
2
3
4
>>> x = itertools.product('ABC', range(3))
>>>
>>> print(list(x))
[('A', 0), ('A', 1), ('A', 2), ('B', 0), ('B', 1), ('B', 2), ('C', 0), ('C', 1), ('C', 2)]

itertools.accumulate

简单来说就是累加。

1
2
3
4
>>> import itertools
>>> x = itertools.accumulate(range(10))
>>> print(list(x))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

itertools.chain

连接多个列表或者迭代器。

1
2
3
>>> x = itertools.chain(range(3), range(4), [3,2,1])
>>> print(list(x))
[0, 1, 2, 0, 1, 2, 3, 3, 2, 1]

itertools.combinations

求列表或生成器中指定数目的元素不重复的所有组合

1
2
3
>>> x = itertools.combinations(range(4), 3)
>>> print(list(x))
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]

itertools.combinations_with_replacement

允许重复元素的组合

1
2
3
>>> x = itertools.combinations_with_replacement('ABC', 2)
>>> print(list(x))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]

itertools.count

就是一个计数器,可以指定起始位置和步长

1
2
3
>>> x = itertools.count(start=20, step=-1)
>>> print(list(itertools.islice(x, 0, 10, 1)))
[20, 19, 18, 17, 16, 15, 14, 13, 12, 11]

itertools.cycle

循环指定的列表和迭代器

1
2
3
>>> x = itertools.cycle('ABC')
>>> print(list(itertools.islice(x, 0, 10, 1)))
['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A']

itertools.dropwhile

按照真值函数丢弃掉列表和迭代器前面的元素

1
2
3
>>> x = itertools.dropwhile(lambda e: e < 5, range(10))
>>> print(list(x))
[5, 6, 7, 8, 9]

itertools.takewhile

与dropwhile相反,保留元素直至真值函数值为假。

1
2
3
>>> x = itertools.takewhile(lambda e: e < 5, range(10))
>>> print(list(x))
[0, 1, 2, 3, 4]

itertools.filterfalse

保留对应真值为False的元素

1
2
3
>>> x = itertools.filterfalse(lambda e: e < 5, (1, 5, 3, 6, 9, 4))
>>> print(list(x))
[5, 6, 9]

itertools.groupby

按照分组函数的值对元素进行分组

1
2
3
4
5
6
>>> x = itertools.groupby(range(10), lambda x: x < 5 or x > 8)                                                                                                 
>>> for condition, numbers in x:
... print(condition, list(numbers))
True [0, 1, 2, 3, 4]
False [5, 6, 7, 8]
True [9]

itertools.islice

上文使用过的函数,对迭代器进行切片

1
2
3
>>> x = itertools.islice(range(10), 0, 9, 2)
>>> print(list(x))
[0, 2, 4, 6, 8]

itertools.repeat

简单的生成一个拥有指定数目元素的迭代器

1
2
3
>>> x = itertools.repeat(0, 5)
>>> print(list(x))
[0, 0, 0, 0, 0]

itertools.zip_longest

类似于zip,不过已较长的列表和迭代器的长度为准

1
2
3
4
5
6
>>> x = itertools.zip_longest(range(3), range(5))
>>> y = zip(range(3), range(5))
>>> print(list(x))
[(0, 0), (1, 1), (2, 2), (None, 3), (None, 4)]
>>> print(list(y))
[(0, 0), (1, 1), (2, 2)]