摘要:Itertools 提供了各种方法,这些方法提供了快速、内存高效且复杂的迭代魔法。听起来对于被称为宝石的东西来说很复杂,对吧?但等等,看看例子,你就会明白为什么它在官方文档中形成了一个“迭代代数”。
Itertools 提供了各种方法,这些方法提供了快速、内存高效且复杂的迭代魔法。听起来对于被称为宝石的东西来说很复杂,对吧?但等等,看看例子,你就会明白为什么它在官方文档中形成了一个“迭代代数”。
从高层次来看,可以根据使用情况将这些来自 itertools 模块的方法分为三类。
无限迭代器 — 生成的迭代器具有无限序列。例如:cycle、count、repeat。终止迭代器 — 生成的迭代器在满足特定条件后终止。例如:accumulate、chain、compress、dropwhile、filterfalse、groupby、islice、starmap、takewhile、pairwise。组合迭代器 — 生成输入元素的组合、排列或类似排列。例如:product、permutations、combinations、 combinations_with_replacement 。此函数将具有相同值或输入键的元素分组。它返回一个包含迭代器的对象。
场景 :给定一个由 W(胜利)和 L(失败)组成的字符串,表示一支队伍的表现,计算最长的胜利连串。
from itertools import groupby game_results = "WWWLLWWWWLWWWWWW" longest_streak = 0 for key, streak in groupby(game_results): if key == "W": longest_streak = max(longest_streak, len(list(streak))) print(longest_streak) # 6解释 :
对字符串进行 groupby 操作返回了 2 个元素——第一个是键,它是分组项的值(即 W 或 L)。第二个是这个分组项的迭代器。记住,迭代器不等于列表。循环可能会让你认为它正在遍历每个字符,但实际上它只运行了 5 次。5 是分组数,与字符串长度 16 相比。由于迭代次数减少,此解决方案将高效运行,并且对于更长的字符串,其扩展性更好。它还将通过直接在分组上工作来避免存储不必要的中间结果。我用 groupby 解决了另一个问题:输入字符串由重复的字符组成,这些字符代表用于编码的键。将其转换为压缩格式,其中字符前面带有它们的频率。
from itertools import groupbydef count_char_occurrences(input_string): result = "" for char, group in groupby(input_string): count = len(list(group)) result += str(count) + char return resultinput_string = "aaaaabbccccde"output = count_char_occurrences(input_string)print(output) # Output: 5a2b4c1d1e当我看到这个问题时,我立即想到了它的安全防护实现。它在任何安全策略中可能只占很小的部分,但请注意我们解决这个问题的优雅性。
使用 cycle 可以无限迭代一个序列。
场景 :想象一下有一个任务列表和一个工作节点列表,你需要将这些任务以轮询的方式分配,以确保没有节点以不公平的方式过载。
from itertools import cycleworkers = ["Node A", "Node B", "Node C"]tasks = ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5", "Task 6", "Task 7"]def assign_tasks(workers, tasks): worker_cycle = cycle(workers) for task in tasks: worker = next(worker_cycle) print(f"{worker}: {task}")assign_tasks(workers, tasks)# Output:# Node A: Task 1# Node B: Task 2# Node C: Task 3# Node A: Task 4# Node B: Task 5# Node C: Task 6# Node A: Task 7解释 :
使用 cycle(workers) 时,我们得到一个迭代器,它会反复遍历 workers 列表。然后,在每次循环遍历任务时,我们访问下一个工作节点,并以循环方式分配任务。这简化了逻辑,使得管理索引或计数器变得更加容易当我们需要从有限输入中获取重复模式时,这种场景非常完美,比如分区或流处理,当你资源有限时。此函数可以帮助你生成包含重复元素的组合。
场景 :想象一下,你正在构建一个多层缓存系统,用户可以为每个级别(L1 和 L2)选择缓存大小,并且可以重复选择相同的大小。生成所有可能的组合
from itertools import combinations_with_replacementlevels = 2 sizes = [16, 32, 64]cache_combinations = list(combinations_with_replacement(sizes, levels))print(cache_combinations)# Output# [(16, 16), (16, 32), (16, 64), (32, 32), (32, 64), (64, 64)]解释 :
该函数生成所有可能的组合,包括重复的组合,例如 (32, 32)。顺序不重要,这就是为什么你会看到 L1=32KB,L2=64KB 只出现一次。这段代码简单,以简洁的方式满足了需求,同时也消除了使用循环或递归的需要。此实现适用于许多组合问题,例如 CPU 设计、硬件仿真。来源:自由坦荡的湖泊AI一点号