python模块百科_为高效而生_itertools【三】
- 一、itertools --- 为高效而生
- 二、无穷迭代器
- 三、根据最短输入序列长度停止的迭代器
- 3.6 groupby()
- 3.7 islice()
- 3.8 starmap()
- 3.9 takewhile()
- 3.10 tee()
一、itertools — 为高效而生
itertools
— 为高效而生。itertools
模块实现一系列迭代器 ,这些迭代器受到APL,Haskell、SML几种语言的启发。
itertools
模块标准化了一个快速、高效利用内存的核心工具集,这些工具本身或组合都很有用。它们一起形成了“迭代器代数”,这使得在纯Python中有可能创建简洁又高效的专用工具。
例如,SML有一个制表工具: tabulate(f)
,它可产生一个序列 f(0), f(1), ...
。在Python中可以组合 map()
和 count()
实现: map(f, count())
。
这些工具及其内置对应物也能很好地配合 operator
模块中的快速函数来使用。 例如,乘法运算符可以被映射到两个向量之间执行高效的点积: sum(starmap(operator.mul, zip(vec1, vec2, strict=True)))
。
二、无穷迭代器
迭代器 | 实参 | 结果 | 示例 |
---|---|---|---|
count() | [start[, step]] | start, start+step, start+2step, … | count(10) --> 10 11 12 13 14 ... |
cycle() | p | p0, p1, … plast, p0, p1, … | cycle('ABCD') --> A B C D A B C D ... |
repeat() | elem [,n] | elem, elem, elem, … 重复无限次或n次 | repeat(10, 3) --> 10 10 10 |
三、根据最短输入序列长度停止的迭代器
迭代器 | 实参 | 结果 | 示例 |
---|---|---|---|
accumulate() | p [,func] | p0, p0+p1, p0+p1+p2, … | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
chain() | p, q, … | p0, p1, … plast, q0, q1, … | chain('ABC', 'DEF') --> A B C D E F |
chain.from_iterable() | iterable – 可迭代对象 | p0, p1, … plast, q0, q1, … | chain.from_iterable(['ABC', 'DEF']) --> A B C D E F |
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), … | compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F |
dropwhile() | pred, seq | seq[n], seq[n+1], … 从pred首次真值测试失败开始 | dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 |
filterfalse() | pred, seq | seq中pred(x)为假值的元素,x是seq中的元素。 | filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 |
groupby() | iterable[, key] | 根据key(v)值分组的迭代器 | |
islice() | seq, [start,] stop [, step] | seq[start:stop:step]中的元素 | islice('ABCDEFG', 2, None) --> C D E F G |
starmap() | func, seq | func(seq[0]), func(seq[1]), … | starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 |
takewhile() | pred, seq | seq[0], seq[1], …, 直到pred真值测试失败 | takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 |
tee() | it, n | it1, it2, … itn 将一个迭代器拆分为n个迭代器 | |
zip_longest() | p, q, … | (p[0], q[0]), (p[1], q[1]), … | zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- |
3.6 groupby()
itertools.groupby()
是一个 Python 内置函数,它可以对可迭代的对象进行分组。这个函数有两个主要参数:一个可迭代的对象和一个键函数。键函数定义了如何将可迭代对象的元素分组。
示例1: 列表奇偶分组
from itertools import groupby
# 创建一个数字列表
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 定义一个函数,用于将数字按奇偶分组
def key_func(n):return n % 2 == 0
# 使用 groupby() 对数字进行分组
for key, group in groupby(numbers, key_func):print(f'key={key}, value = {list(group)}')
# 执行结果
key=False, value = [1]
key=True, value = [2]
key=False, value = [3]
key=True, value = [4]
key=False, value = [5]
key=True, value = [6]
key=False, value = [7]
key=True, value = [8]
key=False, value = [9]
key=True, value = [10]
示例2: 字符串长度分组
from itertools import groupby
words = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'grape']
def key_func(word):return len(word)
for key, group in groupby(words, key_func):print(f'Length {key}: {list(group)}')
# 执行结果
Length 5: ['apple']
Length 6: ['banana', 'cherry']
Length 4: ['date']
Length 10: ['elderberry']
Length 3: ['fig']
Length 5: ['grape']
示例3: 字母分组
from itertools import groupby
letters = ['at', 'bi', 'bc', 'bd', 'ei', 'fe', 'ga', 'gh', 'gi', 'jd']
def key_func(letter):return letter[0]
for key, group in groupby(letters, key_func):print(f'First letter {key}: {list(group)}')
# 执行结果
First letter a: ['at']
First letter b: ['bi', 'bc', 'bd']
First letter e: ['ei']
First letter f: ['fe']
First letter g: ['ga', 'gh', 'gi']
First letter j: ['jd']
3.7 islice()
itertools.islice()
可以从一个迭代器中获取切片
示例1: 无穷迭代器前10个数,下10个数中后5个
from itertools import count, islice
# 创建一个无限递增的数字迭代器
numbers = count(1)
# 使用 islice() 获取前10个数字
first_ten_numbers = islice(numbers, 10)
# 打印前10个数字
print(list(first_ten_numbers))
# 使用 islice() 截取下10个数字中的后5个
first_ten_numbers = islice(numbers, 5, 10)
# 打印这5个数字
print(list(first_ten_numbers))
# 执行结果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[16, 17, 18, 19, 20]
示例2: 10以下素数迭代10次
from itertools import islice, cycledef generate_primes(n):def is_prime(num):if num < 2:return Falsefor i in range(2, int(num ** 0.5) + 1):if num % i == 0:return Falsereturn Truereturn islice(cycle((x for x in range(2, n) if is_prime(x))), n)print(list(generate_primes(10)))
# 执行结果
[2, 3, 5, 7, 2, 3, 5, 7, 2, 3]
3.8 starmap()
itertools.starmap()
是 Python 的一个内置函数,它用于将一个可迭代对象的元素作为参数传递给一个函数,并返回函数的迭代器。
示例 1:执行多个函数
from itertools import starmapdef func1(a, b):return a + bdef func2(a, b):return a * bnumbers = [(1, 2), (3, 4), (5, 6)]
result1 = list(starmap(func1, numbers))
result2 = list(starmap(func2, numbers))
print(result1)
print(result2)
# 执行结果
[3, 7, 11]
[2, 12, 30]
示例 2:将多个列表的元素作为参数传递给函数
from itertools import starmap, zip_longestdef add_elements(a, b):return a + blist1 = [1, 2, 3]
list2 = [4, 5, 6]
zipped = list(zip_longest(list1, list2)) # 使用 None 填充较短的列表
result = list(starmap(add_elements, zipped))
print(result)
# 执行结果
[5, 7, 9]
示例 3:在多线程应用中并行处理数据
from itertools import starmap, islice
from concurrent.futures import ThreadPoolExecutor
def process_data(data):# 这里可以执行一些耗时的数据处理任务return data * 2with ThreadPoolExecutor() as executor:data = range(100) # 大量的数据需要处理chunk_size = 10 # 将数据分成小块进行处理以提高效率chunks = list(islice(data, chunk_size)) # 将数据分成块print(chunks)chunkslist = [[x] for x in chunks]results = list(starmap(process_data, chunkslist)) # 使用 starmap() 将块传递给处理函数并收集结果print(results)
# 执行结果
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
3.9 takewhile()
itertools.takewhile()
可以从一个迭代器中取出元素,直到满足某个条件为止。以下是代码示例:
示例1: 取出列表中小于5的数
import itertools
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list(itertools.takewhile(lambda x: x < 5, numbers))
print(result)
numbers = [8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list(itertools.takewhile(lambda x: x < 5, numbers))
print(result)
# 执行结果
[1, 2, 3, 4]
[]
示例2: 取连续小写字母
import itertools
text = "HelloWorld"
result = list(itertools.takewhile(lambda x: x.islower(), text))
print(result)
text = "helloWorld"
result = list(itertools.takewhile(lambda x: x.islower(), text))
print(result)
# 执行结果
[]
['h', 'e', 'l', 'l', 'o']
3.10 tee()
itertools.tee()
用于复制迭代器。这意味着你可以得到原始迭代器的多个副本,这些副本可以独立地迭代。
示例1: 复制一个字符串的多个副本
import itertools
s = "hello"
t1, t2 = itertools.tee(s)
print(list(t1))
print(list(t2))
# 执行结果
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
**示例2:**生成多个斐波那契数列的副本
import itertools
def fibonacci(n):a, b = 0, 1i = 0while i < n:yield aa, b = b, a + bi += 1
fib_seq1, fib_seq2, fib_seq3 = itertools.tee(fibonacci(5), 3) # 创建斐波那契数列的三个副本
print(list(fib_seq1))
print(list(fib_seq2))
print(list(fib_seq3))
# 执行结果
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5]
may the odds be ever in your favor ~