Python itertools指南

815 阅读7分钟

那些 迭代比你想象中的更为强大。

什么是迭代?

简单的说,迭代是可以被 for循环使用的数据类型,Python中常见的迭代器是列表。

                            
  1. colors = [ 'red', 'orange', 'yellow', 'green']

在上面的例子中,我们创建了一个字符串列表,我们已经给这个列表命名为 colors

我们可以使用 for循环来迭代,下面的的列表中将输出列表中的每一个元素。

                                    
  1. for color in colors :

  2.     print(color )

Python中有许多不同种类的迭代,但是在本教程中,我们将使用列表。

要求

我们必须导入该 itertools模块才能使用它,我们还将导入 operator模块。

以下所有示例将包含这些导入。

  1. import itertools

  2. import operator

itertools

accumulate()

  1. itertools.accumulate(iterable [,func])

该函数会返回函数结果的迭代器,函数可以是变量来传递。 accumulate()函数将一个函数作为参数。它也需要一个迭代。它返回所有的结果,结果本身包含在一个迭代器中。

  • Example

  1. data = [1, 2, 3, 4, 5]

  2. result = itertools.accumulate(data, operator.mul)

  3. for each in result:

  4.    print(each)

  • Example

  1. 1

  2. 2

  3. 6

  4. 24

  5. 120

operator.mul需要两个数字并乘以它们

                                                
  1. >>> import operator

  2. >>> operator.mul (1, 2)

  3. 2

  4. >>> operator.mul (2, 3)

  5. 6

  6. >>> operator.mul (6, 4)

  7. 24

  8. >>> operator.mul (24, 5)

  9. 120

在下一个例子中将会使用该 max功能

  • Example

  1. data = [5, 2, 6, 4, 5, 9, 1]

  2. result = itertools.accumulate(data, max)

  3. for each in result:

  4.    print(each)

  • Example

  1. 5

  2. 5

  3. 6

  4. 6

  5. 6

  6. 9

  7. 9

max函数返回最大的项

                                                        
  1. >>> max(5, 2)

  2. 5

  3. >>> max(5, 6)

  4. 6

  5. >>> max(6, 4)

  6. 6

  7. >>> max(6, 5)

  8. 6

  9. >>> max(6, 9)

  10. 9

  11. >>> max(9, 1)

  12. 9

传递函数是可选的

  • Example

  1. data = [5, 2, 6, 4, 5, 9, 1]

  2. result = itertools.accumulate(data)

  3. for each in result:

  4.    print(each)

  • Output

  1. 5

  2. 7

  3. 13

  4. 17

  5. 22

  6. 31

  7. 32

如果没有指定功能,项目将相加。

  1. 5

  2. 5 + 2 = 7

  3. 7 + 6 = 13

  4. 13 + 4 = 17

  5. 17 + 5 = 22

  6. 22 + 9 = 31

  7. 31 + 1 = 32

count()

  1. itertools.count(start=0, step=1)

迭代器每次返回 start+step的值

  • Example

返回 1-10之间的所有奇数

                                                                
  1. for i in itertools. count( 1, 2 ):

  2.     if i > 10:

  3.         break

  4.     else:

  5.         print( i)

  • Output

  1. 1

  2. 3

  3. 5

  4. 7

  5. 9

cycle()

  1. itertools.cycle(iterable)

无限循环迭代器中的每一个元素

  • Example

  1. colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet']

  2. for color in itertools.cycle(colors):

  3.    print(color)

在上面的代码中,我们创建一个列表,然后我们循环或循环遍历这个列表。通常,一个 for循环逐步循环,直到它到达结束。如果一个列表有 3个项目,循环将重复3次。但是如果我们使用这个 cycle()功能的话。当我们到达迭代的结束时,我们从一开始就重新开始。

  • Output

  1. red

  2. orange

  3. yellow

  4. green

  5. blue

  6. indigo

  7. violet

  8. red

  9. orange

  10. yellow

  11. green

  12. ...

repeat()

  1. itertools.repeat(object[, times])

此功能将一遍又一遍地重复一个对象,除非有一个 times次数。

  • Example

  1. for i in itertools.repeat("spam"):

  2.    print(i)

在上面的代码中,我们创建一个可重复的迭代 spam,它会不停地循环输出 spam

  • Output

  1. spam

  2. spam

  3. spam

  4. spam

  5. spam

  6. spam

  7. ...

  • Example

  1. for i in itertools.repeat("spam", 3):

  2.    print(i)

如果我们使用 times参数,可以限制它将重复的次数。

  • Output

  1. spam

  2. spam

  3. spam

在这个例子中, spam只重复三次

chain()

  1. itertools.chain(*iterables)

此函数需要一系列迭代,并将其返回为一个长的迭代。

  • Example

  1. colors = ['red', 'orange', 'yellow', 'green', 'blue']

  2. shapes = ['circle', 'triangle', 'square', 'pentagon']

  3. result = itertools.chain(colors, shapes)

  4. for each in result:

  5.    print(each)

  • Output

  1. red

  2. orange

  3. yellow

  4. green

  5. blue

  6. circle

  7. triangle

  8. square

  9. pentagon

compress()

  1. itertools.compress(data, selectors)

这个函数可以使用另一个过滤器来迭代

  • Example

  1. shapes = ['circle', 'triangle', 'square', 'pentagon']

  2. selections = [True, False, True, False]

  3. result = itertools.compress(shapes, selections)

  4. for each in result:

  5.    print(each)

  • Output

  1. circle

  2. square

dropwhile()

  1. itertools.dropwhile(predicate, iterable)

做一个迭代器,只要返回为 true,就从 iterable中删除元素,否则就返回后面的每个元素

  • Example

  1. data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]

  2. result = itertools.dropwhile(lambda x: x < 5, data)

  3. for each in result:

  4.    print(each)

  • Output

  1. 5

  2. 6

  3. 7

  4. 8

  5. 9

  6. 10

  7. 1

好。这可以令人困惑 代码说,当项目小于5时,删除每个项目。遇到不少于5的项目后,返回剩下的项目。这就是为什么最后一个被归还。

  • Step Through It

  1. 1 < 5:  True,  drop

  2. 2 < 5:  True,  drop

  3. 3 < 5:  True,  drop

  4. 4 < 5:  True,  drop

  5. 5 < 5:  False, return surviving items

groupby()

  1. itertools.groupby(iterable, key=None)

简单地说,这个功能将事情集中在一起

  • Example

  1. robots = [

  2.    {

  3.        'name': 'blaster',

  4.        'faction': 'autobot'

  5.    },

  6.    {

  7.        'name': 'galvatron',

  8.        'faction': 'decepticon'

  9.    },

  10.    {

  11.        'name': 'jazz',

  12.        'faction': 'autobot'

  13.    },

  14.    {

  15.        'name': 'metroplex',

  16.        'faction': 'autobot'

  17.    },

  18.    {

  19.        'name': 'megatron',

  20.        'faction': 'decepticon'

  21.    },

  22.    {

  23.        'name': 'starcream',

  24.        'faction': 'decepticon'

  25.    }

  26. ]

  27. for key, group in itertools.groupby(robots, key=lambda x: x['faction']):

  28.    print(key)

  29.    print(list(group))

  • Output

  1. autobot

  2. [{'name': 'blaster', 'faction': 'autobot'}]

  3. decepticon

  4. [{'name': 'galvatron', 'faction': 'decepticon'}]

  5. autobot

  6. [{'name': 'jazz', 'faction': 'autobot'}, {'name': 'metroplex', 'faction': 'autobot'}]

  7. decepticon

  8. [{'name': 'megatron', 'faction': 'decepticon'}, {'name': 'starcream', 'faction': 'decepticon'}]

filterfalse()

  1. itertools.filterfalse(predicate, iterable)

这个函数使迭代器从 iterable中过滤元素,只返回的元素 False

  • Example

  1. data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]

  2. result = itertools.filterfalse(lambda x: x < 5, data)

  3. for each in result:

  4.    print(each)

  • Output

  1. 5

  2. 6

  3. 7

  4. 8

  5. 9

  6. 10

  • Debug

  1. 1 < 5:  True,  drop

  2. 2 < 5:  True,  drop

  3. 3 < 5:  True,  drop

  4. 4 < 5:  True,  drop

  5. 5 < 5:  False, keep

  6. 6 < 5:  False, keep

  7. 7 < 5:  False, keep

  8. 8 < 5:  False, keep

  9. 9 < 5:  False, keep

  10. 10 < 5:  False, keep

  11. 1 < 5:  True,  drop

islice()

  1. itertools.islice(iterable, start, stop[, step])

这个功能非常像切片,此功能允许您剪切一个可迭代的片段

  • Example

  1. colors = ['red', 'orange', 'yellow', 'green', 'blue']

  2. few_colors = itertools.islice(colors, 2)

  3. for each in few_colors:

  4.    print(each)

  • Output

  1. red

  2. orange

starmap()

  1. itertools.starmap(function, iterable)

此函数使迭代器使用从 iterable获取的参数来计算函数

  • Example

  1. data = [(2, 6), (8, 4), (7, 3)]

  2. result = itertools.starmap(operator.mul, data)

  3. for each in result:

  4.    print(each)

  • Output

  1. 12

  2. 32

  3. 21

  • Step Through

  1. >>> operator.mul(2, 6)

  2. 12

  3. >>> operator.mul(8, 4)

  4. 32

  5. >>> operator.mul(7, 3)

  6. 21

tee()

  1. itertools.tee(iterable, n=2)

从单个迭代中返回 n个独立迭代器

  • Example

  1. colors = ['red', 'orange', 'yellow', 'green', 'blue']

  2. alpha_colors, beta_colors = itertools.tee(colors)

  3. for each in alpha_colors:

  4.    print(each)

  5. print('..')

  6. for each in beta_colors:

  7.    print(each)

默认值为2,但您可以根据需要进行许多操作。

  • Output

  1. red

  2. orange

  3. yellow

  4. green

  5. blue

  6. ..

  7. red

  8. orange

  9. yellow

  10. green

  11. blue

takewhile()

  1. itertools.takwwhile(predicate, iterable)

这是相反的 dropwhile(),只要返回为 true,该函数就可以使用迭代器并从 iterable返回元素

  • Example

  1. data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]

  2. result = itertools.takewhile(lambda x: x < 5, data)

  3. for each in result:

  4.    print(each)

  • Output

  1. 1

  2. 2

  3. 3

  4. 4

  • Step Through It

  1. 1 < 5:  True,  keep going

  2. 2 < 5:  True,   keep going

  3. 3 < 5:  True,   keep going

  4. 4 < 5:  True,   keep going

  5. 5 < 5:  False, stop and drop

zip_longest()

  1. itertools.zip_longest(*iterables, fillvalue=None)

此函数使迭代器聚合每个迭代的元素,如果迭代长度不均匀,则缺少的值将被填充为 fillvalue。迭代继续,直到最长的迭代耗尽。

  • Example

  1. colors = ['red', 'orange', 'yellow', 'green', 'blue']

  2. data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  3. for each in itertools.zip_longest(colors, data, fillvalue=None):

  4.    print(each)

  • Output

  1. ('red', 1)

  2. ('orange', 2)

  3. ('yellow', 3)

  4. ('green', 4)

  5. ('blue', 5)

  6. (None, 6)

  7. (None, 7)

  8. (None, 8)

  9. (None, 9)

  10. (None, 10)

product()

此函数从一系列迭代创建笛卡尔乘积。

  • Example

  1. num_data = [1, 2, 3]

  2. alpha_data = ['a', 'b', 'c']

  3. result = itertools.product(num_data, alpha_data)

  4. for each in result:

  5.    print(each)

  • Output

  1. (1, 'a')

  2. (1, 'b')

  3. (1, 'c')

  4. (2, 'a')

  5. (2, 'b')

  6. (2, 'c')

  7. (3, 'a')

  8. (3, 'b')

  9. (3, 'c')

想象一下这样的桌子:

  1.      a     b      c

  2. 1     a1    b1     c1

  3. 2     a2    b2     c3

  4. 3     a3    b3     b3

permutations()

  1. itertools.permutations(iterable, r=None)

  • Example

  1. alpha_data = ['a', 'b', 'c']

  2. result = itertools.permutations(alpha_data)

  3. for each in result:

  4.    print(each)

  • Output

  1. ('a', 'b', 'c')

  2. ('a', 'c', 'b')

  3. ('b', 'a', 'c')

  4. ('b', 'c', 'a')

  5. ('c', 'a', 'b')

  6. ('c', 'b', 'a')

combinations()

  1. itertools.combinations(iterable, r)

此函数需要一个迭代和一个整数,这将创建具有 r成员的所有独特组合。

  • Example

  1. shapes = ['circle', 'triangle', 'square', ]

  2. result = itertools.combinations(shapes, 2)

  3. for each in result:

  4.    print(each)

在这段代码中,我们使用2个成员组合所有组合。

  • Output

  1. ('circle','triangle')

  2. ('circle','square')

  3. ('triangle','square')

  • Example

  1. result = itertools.combinations(shapes, 3)

  2. for each in result:

  3.    print(each)

在这段代码中,我们使用3个成员组合所有组合。这有点不太令人兴奋。

  • Output

  1. ('circle', 'triangle', 'square')

combinationswithreplacement()

  1. itertools.combinations_with_replacement(iterable, r)

这一个就像 combinations()功能一样,但是这个可以让单个元素重复一次。

  • Example

  1. shapes = ['circle', 'triangle', 'square', ]

  2. result = itertools.combinations_with_replacement(shapes, 2)

  3. for each in result:

  4.    print(each)

  • Output

  1. ('circle', 'circle')

  2. ('circle', 'triangle')

  3. ('circle', 'square')

  4. ('triangle', 'triangle')

  5. ('triangle', 'square')

  6. ('square', 'square')