Python迭代工具函数是什么?

根据python的文档,itertools是一个python模块,为处理python迭代器提供了一套快速和高效的工具。这些工具可以单独或组合使用,可以以快速和高效的方式简洁地创建和处理迭代器。

itertools模块包含了一些函数,使得在处理大量数据时更容易使用迭代器。itertools函数可以对现有的迭代器进行操作,从而创建更复杂的python迭代器。

此外,itertools可以帮助开发人员在处理迭代器时减少错误,并编写更清晰、可读性更强、易于维护的代码。

python itertools中的迭代器类型

根据itertools模块提供的迭代器的功能,它们可以分为以下几种类型:

#1. 无限迭代器

这些迭代器允许您处理无限序列,并且如果没有条件来跳出循环,可以无限循环运行。当模拟无限循环或生成无限序列时,此类迭代器非常有用。itertools有三个无限迭代器,分别是count()、cycle()repeat()

#2. 组合迭代器

组合迭代器包括可以用于处理笛卡尔积和对可迭代对象中的元素执行组合和排列的函数。当尝试找到可迭代对象中元素的所有可能排列或组合时,这些函数是首选函数。itertools有四种组合迭代器,分别是product()、permutations()、combinations()combinations_with_replacement()

#3. 以最短输入序列为终止的迭代器

这些是用于有限序列的终止迭代器,并根据使用的函数类型生成输出。这些终止迭代器的示例包括:accumulate()、chain()、chain.from_iterable()、compress()、dropwhile()、filterfalse()、groupby()、islice()、pairwise()、starmap()、takewhile()、tee()zip_longest()

让我们看看不同的itertools函数如何根据它们的类型工作:

无限迭代器

这三个无限迭代器包括:

#1. count()

count(start, step)函数从起始值开始生成一个无限序列的数字。该函数接受两个可选参数:startstep。参数start设置数字序列应该从哪里开始。如果未提供起始值,默认从0开始。参数step设置每个连续数字之间的差值。默认的步长值为1。

import itertools

# 定义一个列表x和y
x = [7, 8]
y = [1, 2, 3]

# 使用product()计算x和y的笛卡尔积
cartesian_product = itertools.product(x, y)
for item in cartesian_product:
    print(item)

输出:

[7, 1]
[7, 2]
[7, 3]
[8, 1]
[8, 2]
[8, 3]

#2. permutations()

permutations(iterable, r)函数用于计算一个序列的所有排列组合。可选参数r用于指定排列的长度,如果不指定,默认为序列的长度。

例如,对于序列[1, 2, 3],permutations()将返回[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]。

在计算排列组合时,元素的顺序很重要。也就是说,对于序列[1, 2, 3],(1, 2, 3)和(3, 2, 1)被视为不同的排列。

import itertools

# 定义一个序列
seq = [1, 2, 3]

# 计算序列的所有排列组合
permutations = itertools.permutations(seq)
for item in permutations:
    print(item)

输出:

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

#3. combinations()

combinations(iterable, r)函数用于计算一个序列的所有组合。可选参数r用于指定组合的长度,如果不指定,默认为序列的长度。

与permutations()不同的是,combinations()中的元素顺序不重要。也就是说,对于序列[1, 2, 3],(1, 2, 3)和(3, 2, 1)被视为相同的组合。

import itertools

# 定义一个序列
seq = [1, 2, 3]

# 计算序列的所有组合
combinations = itertools.combinations(seq)
for item in combinations:
    print(item)

输出:

(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 3)

#4. combinations_with_replacement()

combinations_with_replacement(iterable, r)函数用于计算一个序列的所有组合,允许元素重复。可选参数r用于指定组合的长度,如果不指定,默认为序列的长度。

与combinations()不同,combinations_with_replacement()中的元素顺序不重要,并且允许元素重复。

import itertools

# 定义一个序列
seq = [1, 2, 3]

# 计算序列的所有组合(允许元素重复)
combinations_with_replacement = itertools.combinations_with_replacement(seq)
for item in combinations_with_replacement:
    print(item)

输出:

(1,)
(2,)
(3,)
(1, 1)
(1, 2)
(1, 3)
(2, 2)
(2, 3)
(3, 3)
from itertools import product
# product() with the optional repeat argument
print("product() with the optional repeat argument ")
print(list(product('abc', repeat = 2)))

# product with no repeat
print("product() without an optional repeat argument")
print(list(product([7,8], [1,2,3])))

输出结果

product() with the optional repeat argument 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]
product() without an optional repeat argument
[(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)]

#2. permutations()

permutations(iterable, group_size)返回可迭代对象的所有可能排列。排列表示集合中元素的排列方式。permutations()接受一个可选参数group_size。如果未指定group_size ,则生成的排列大小将与传入函数的可迭代对象的长度相同

import itertools
numbers = [1, 2, 3]
sized_permutations = list(itertools.permutations(numbers,2))
unsized_permuatations = list(itertools.permutations(numbers))

print("permutations with a size of 2")
print(sized_permutations)
print("permutations with no size argument")
print(unsized_permuatations)

输出结果

permutations with a group size of 2
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
permutations with no size argument
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

#3. combinations()

combinations(iterable, size)返回可迭代对象中给定长度的所有可能组合。参数size 指定每个组合的大小。

结果是有序的。组合与排列略有不同。在排列中,顺序很重要,但在组合中,顺序不重要。例如,在[a, b, c]中,有6个排列:ab,ac,ba,bc,ca,cb,但只有3个组合ab,ac,bc。

import itertools
numbers = [1, 2, 3,4]
size2_combination = list(itertools.combinations(numbers,2))
size3_combination = list(itertools.combinations(numbers, 3))

print("combinations with a size of 2")
print(size2_combination)
print("combinations with a size of 3")
print(size3_combination)

输出结果:

combinations with a size of 2
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
combinations with a size of 3
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

#4. combinations_with_replacement()

combinations_with_replacement(iterable, size)生成可迭代对象中给定长度的所有可能组合,并允许输出组合中有重复的元素。size确定生成的组合的大小。

此函数与combinations()的不同之处在于它提供了可以重复多次使用一个元素的组合。例如,您可以获得(1,1)这样的组合,而combination()不行。

import itertools
numbers = [1, 2, 3,4]

size2_combination = list(itertools.combinations_with_replacement(numbers,2))
print("使用替换组合 => 大小为2")
print(size2_combination)

输出

使用替换组合 => 大小为2
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 4)]

终止迭代器

这包括以下迭代器:

#1. accumulate()

accumulate(iterable, function)接受一个可迭代对象和一个可选的第二个参数,该参数是一个函数。然后返回在每次迭代中将该函数应用于可迭代对象的元素上的累积结果。如果没有传递函数,则执行加法并返回累积结果。

import itertools
import operator
numbers = [1, 2, 3, 4, 5]

# 累积数字的和
accumulated_val = itertools.accumulate(numbers)
accumulated_mul = itertools.accumulate(numbers, operator.mul)
print("没有使用函数的累积结果")
print(list(accumulated_val))
print("使用乘法的累积结果")
print(list(accumulated_mul))

输出:

没有使用函数的累积结果
[1, 3, 6, 10, 15]
使用乘法的累积结果
[1, 2, 6, 24, 120]

#2. chain()

chain(iterable_1, iterable_2, …)接受多个可迭代对象,并将它们连接在一起,生成一个包含来自传递给chain()函数的可迭代对象的值的单个可迭代对象

import itertools

letters = ['a', 'b', 'c', 'd']
numbers = [1, 2, 3]
colors = ['red', 'green', 'yellow']

# 将字母和数字连在一起
chained_iterable = list(itertools.chain(letters, numbers, colors))
print(chained_iterable)

输出:

['a', 'b', 'c', 'd', 1, 2, 3, 'red', 'green', 'yellow']

#3. chain.from_iterable()

chain.from_iterable(iterable)这个函数与chain()类似。但是,它与chain的不同之处在于它只接受一个包含子可迭代对象的单个可迭代对象,并将它们连接在一起。

import itertools

letters = ['a', 'b', 'c', 'd']
numbers = [1, 2, 3]
colors = ['red', 'green', 'yellow']

iterable = ['hello',colors, letters, numbers]
chain = list(itertools.chain.from_iterable(iterable))
print(chain)

输出:

['h', 'e', 'l', 'l', 'o', 'red', 'green', 'yellow', 'a', 'b', 'c', 'd', 1, 2, 3]

#4. compress()

compress(data,selectors)接受两个参数,data是一个可迭代对象,selectors是一个包含布尔值true和false的可迭代对象。1,0也可以用作布尔值true和false的替代。compress()然后使用传递的selectors中的相应元素过滤传递的data

selector中的值true1对应的data中的值将被选中,而与false0对应的其余值将被忽略。如果在selectors中传递的布尔值少于data中的项目数量,则超过传递的布尔值的所有元素将被忽略。

import itertools

# data has 10 items
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
# passing in 9 selector items
selectors = [true, false, 1, false, 0, 1, true, false, 1]

# select elements from data based on selectors
filtered_data = list(itertools.compress(data, selectors))
print(filtered_data)

输出:

['a', 'c', 'f', 'g', 'i']

#5. dropwhile()

dropwhile(function,sequence)接受一个带有返回true或false的条件的函数和一个值序列。然后删除所有值,直到传递的条件返回false。一旦条件返回false,其余的元素都将包括在其结果中,无论它们返回true还是false。

import itertools

numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

# drop elements until the passed condition is false
filtered_numbers = list(itertools.dropwhile(lambda x: x < 5, numbers))
print(filtered_numbers)

输出:

[5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

#6. filterfalse()

filterfalse(function,sequence)接受一个带有返回true或false的条件的函数和一个序列。然后返回序列中不满足函数中条件的值。 

import itertools

numbers = [1, 2, 3, 4, 2, 3 5, 6, 5, 8, 1, 2, 3, 6, 2, 7, 4, 3]

# filter elements for which condition is false
filtered_numbers = list(itertools.filterfalse(lambda x: x < 4, numbers))
print(filtered_numbers)

输出:

[4, 5, 6, 5, 8, 6, 7, 4]

#7. groupby()

groupby(iterable,key)接受一个可迭代对象和一个键,然后创建一个迭代器,返回连续的键和组。为了使其工作,传递给它的可迭代对象需要在相同的键函数上排序。键函数为可迭代对象中的每个元素计算一个键值。

import itertools

input_list = [("domestic", "cow"), ("domestic", "dog"), ("domestic", "cat"),("wild", "lion"), ("wild", "zebra"), ("wild", "elephant")]
classification = itertools.groupby(input_list,lambda x: x[0])
for key,value in classification:
  print(key,":",list(value))

输出:

domestic : [('domestic', 'cow'), ('domestic', 'dog'), ('domestic', 'cat')]
wild : [('wild', 'lion'), ('wild', 'zebra'), ('wild', 'elephant')]

#8. islice()

islice(iterable, start, stop, step) 允许您使用传递的 start,stop step 值对可迭代对象进行切片。 step参数是可选的。计数从0开始,并且不包括 stop 号上的项目。

import itertools

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

# 在范围内选择元素
selected_numbers = list(itertools.islice(numbers, 2, 10))
selected_numbers_step= list(itertools.islice(numbers, 2, 10,2))
print("不设置步长值的islice")
print(selected_numbers)
print("步长值为2的islice")
print(selected_numbers_step)

输出:

不设置步长值的islice
[3, 4, 5, 6, 7, 8, 9, 10]
步长值为2的islice
[3, 5, 7, 9]

#9. pairwise()

pairwise(iterable) 返回从传递给它的可迭代对象中按照它们在可迭代对象中出现的顺序连续取出的重叠的一对值。如果传递给它的可迭代对象少于两个值,则pairwise()的结果将为空。

from itertools import pairwise

numbers = [1, 2, 3, 4, 5, 6, 7, 8]
word = 'world'
single = ['a']

print(list(pairwise(numbers)))
print(list(pairwise(word)))
print(list(pairwise(single)))

输出:

[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
[('w', 'o'), ('o', 'r'), ('r', 'l'), ('l', 'd')]
[]

#10. starmap()

starmap(function, iterable)是在参数已经被分组成元组时使用的map()函数。starmap()将函数应用于传递给它的可迭代对象的元素。可迭代对象应该具有以元组为组的元素。

import itertools

iter_starmap = [(123, 63, 13), (5, 6, 52), (824, 51, 9), (26, 24, 16), (14, 15, 11)]
print (list(itertools.starmap(min, iter_starmap)))

输出:

[13, 5, 9, 16, 11]

#11. takewhile()

takewhile(function, iterable)的工作方式与dropwhile()相反。takewhile()接受一个带有要评估的条件和一个可迭代对象的函数。然后,它包括满足函数中条件的可迭代对象中的所有元素,直到返回false。一旦返回false,就会忽略可迭代对象中的所有后续元素。

import itertools

numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

# 删除满足条件的元素
filtered_numbers = list(itertools.takewhile(lambda x: x < 5, numbers))
print(filtered_numbers)

输出:

[1, 2, 3, 4]

#12. tee()

tee(iterable, n)接受一个可迭代对象并返回多个独立的迭代器。返回的迭代器数量由n设置,默认为2。

import itertools

numbers = [1, 2, 3, 4, 5]

# 从numbers创建两个独立的迭代器
iter1, iter2 = itertools.tee(numbers, 2)
print(list(iter1))
print(list(iter2))

输出:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

#13. zip_longest()

zip_longest(iterables, fillvalue)接受多个迭代器和一个fillvalue。然后返回一个迭代器,该迭代器聚合了传递给它的每个迭代器的元素。如果迭代器的长度不同,则缺失的值将使用传递给函数的fillvalue替换,直到最长的可迭代对象耗尽。

import itertools

names = ['john', 'mathew', 'mary', 'alice', 'bob', 'charlie', 'fury']
ages = [25, 30, 12, 13, 42]

# 结合名字和年龄,用破折号填充缺失的年龄
combined = itertools.zip_longest(names, ages, fillvalue="-")

for name, age in combined:
    print(name, age)

输出:

john 25
mathew 30
mary 12
alice 13
bob 42
charlie -
fury -

结论

python的itertools是python开发人员的重要工具集。python的itertools在函数式编程、数据处理和转换、数据过滤和选择、分组和聚合、组合迭代器、组合数学以及处理无限序列时被广泛使用。

作为python开发人员,学习itertools将对您大有裨益,因此请确保使用本文来熟悉python itertools。

类似文章