0

0

python中itertools模块有哪些常用功能?

下次还敢

下次还敢

发布时间:2025-09-16 18:32:01

|

213人浏览过

|

来源于php中文网

原创

itertools模块是Python中处理迭代任务的高效工具,提供惰性求值和内存友好的迭代器。其核心功能包括:无限迭代器(如count、cycle、repeat)用于生成无限序列;组合生成器(product、permutations、combinations等)简化复杂组合逻辑;链式与过滤工具(chain、islice、groupby)优化数据流处理。这些函数基于C实现,性能优越,特别适合处理大数据集或性能敏感场景,能显著减少内存占用并提升代码简洁性与执行效率。

python中itertools模块有哪些常用功能?

Python的

itertools
模块,在我看来,简直是处理序列和迭代任务的“瑞士军刀”。它提供了一系列高效、内存友好的迭代器函数,用于创建复杂的迭代模式,处理序列的组合、排列、重复以及无限序列等多种场景,是Python在数据流处理和算法实现上的一个强大且常常被低估的利器。它能让你用更简洁、更Pythonic的方式写出性能更好的代码,尤其是在处理大型数据集时,其优势尤为明显。

解决方案

当我们需要在Python中高效地处理迭代器、生成各种序列组合或执行复杂的循环逻辑时,

itertools
模块是我的首选。它之所以高效,是因为其内部实现多为C语言,并且采用了惰性计算(lazy evaluation)的策略,即只在需要时才生成下一个元素,这极大地节省了内存。

我们通常会将

itertools
的功能大致分为几类:

  1. 无限迭代器:

    立即学习Python免费学习笔记(深入)”;

    • count(start=0, step=1)
      : 生成一个从
      start
      开始,以
      step
      为步长的无限递增序列。这在需要一个无限计数器时非常有用,比如生成唯一的ID或者模拟无限循环。
      import itertools
      # 从10开始,每次加2的无限序列
      # for i in itertools.count(10, 2):
      #     print(i) # 10, 12, 14, ... (会一直打印下去)
      # 通常会结合islice来取有限个
      for i in itertools.islice(itertools.count(10, 2), 3):
          print(i) # 输出: 10, 12, 14
    • cycle(iterable)
      : 将可迭代对象中的元素无限循环。这对于需要重复播放某个序列的场景非常方便,比如轮播图、游戏中的背景音乐序列等。
      # for item in itertools.cycle(['A', 'B', 'C']):
      #     print(item) # A, B, C, A, B, C, ... (无限循环)
      # 同样结合islice
      for item in itertools.islice(itertools.cycle(['A', 'B', 'C']), 5):
          print(item) # 输出: A, B, C, A, B
    • repeat(object[, times])
      : 重复生成
      object
      。如果指定了
      times
      ,则重复指定次数;否则无限重复。
      for _ in itertools.repeat('hello', 3):
          print(_) # 输出: hello, hello, hello
  2. 组合生成器:

    • product(*iterables, repeat=1)
      : 生成多个可迭代对象中元素的笛卡尔积。这就像多层嵌套循环,但更简洁、高效。
      # 相当于 for x in 'AB': for y in '12': print(x, y)
      for p in itertools.product('AB', '12'):
          print(p) # 输出: ('A', '1'), ('A', '2'), ('B', '1'), ('B', '2')
      # repeat 参数用于重复单个可迭代对象
      for p in itertools.product('ABC', repeat=2):
          print(p) # 输出: ('A', 'A'), ('A', 'B'), ('A', 'C'), ..., ('C', 'C')
    • permutations(iterable, r=None)
      : 生成
      iterable
      中所有长度为
      r
      的排列。元素不重复,顺序敏感。
      for p in itertools.permutations('ABC', 2):
          print(p) # 输出: ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')
    • combinations(iterable, r)
      : 生成
      iterable
      中所有长度为
      r
      的组合。元素不重复,顺序不敏感。
      for c in itertools.combinations('ABC', 2):
          print(c) # 输出: ('A', 'B'), ('A', 'C'), ('B', 'C')
    • combinations_with_replacement(iterable, r)
      : 生成
      iterable
      中所有长度为
      r
      的带重复元素的组合。
      for c in itertools.combinations_with_replacement('ABC', 2):
          print(c) # 输出: ('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')
  3. 链式和过滤:

    • chain(*iterables)
      : 将多个可迭代对象串联起来,形成一个单一的迭代器。
      for item in itertools.chain('ABC', 'DEF'):
          print(item) # 输出: A, B, C, D, E, F
    • islice(iterable, start, stop[, step])
      : 像切片一样从可迭代对象中获取指定范围的元素,但返回的是一个迭代器,不会一次性加载所有数据。
      data = range(1000)
      # 获取前5个元素
      for i in itertools.islice(data, 5):
          print(i) # 输出: 0, 1, 2, 3, 4
      # 从第5个开始,到第10个(不包含),步长为2
      for i in itertools.islice(data, 5, 10, 2):
          print(i) # 输出: 5, 7, 9
    • groupby(iterable, key=None)
      : 将连续的相同元素分组。这需要先对数据进行排序才能发挥最大作用。
      data = [('A', 1), ('A', 2), ('B', 3), ('B', 4), ('A', 5)]
      # 需要先排序,否则只会对连续的相同key进行分组
      data.sort(key=lambda x: x[0]) # 排序后: [('A', 1), ('A', 2), ('A', 5), ('B', 3), ('B', 4)]
      for key, group in itertools.groupby(data, key=lambda x: x[0]):
          print(f"Key: {key}, Group: {list(group)}")
          # 输出:
          # Key: A, Group: [('A', 1), ('A', 2), ('A', 5)]
          # Key: B, Group: [('B', 3), ('B', 4)]

这些只是

itertools
模块中我个人觉得最常用和最有代表性的一些功能。通过它们,我们能以一种非常优雅且高效的方式解决很多迭代相关的编程挑战。

为什么
itertools
在处理大数据或性能敏感场景下如此重要?

在我看来,

itertools
在处理大数据或对性能有严格要求的场景中,其重要性体现在几个核心方面。最关键的一点是它彻底贯彻了惰性求值(Lazy Evaluation)的理念。当你在处理一个可能包含数百万甚至数十亿条记录的数据集时,如果使用列表推导式(List Comprehensions)或传统的循环并创建中间列表,内存很快就会被耗尽。而
itertools
中的所有函数都返回迭代器,这意味着它们不会一次性将所有结果加载到内存中,而是在你每次请求下一个元素时才计算并生成它。

举个例子,假设你需要生成一个非常大的数字序列,然后对其进行一些操作。如果你写

numbers = list(range(1_000_000_000))
,你的程序可能会直接崩溃,因为这会尝试在内存中创建包含十亿个整数的列表。但如果使用
itertools.count()
或者直接用
range()
(在Python 3中
range
本身就是迭代器),然后配合
itertools.islice()
,你就可以在不消耗大量内存的情况下,按需处理这个“无限”或“巨大”的序列。

import itertools
import sys

# 尝试创建1亿个元素的列表,可能导致内存问题
# large_list = list(range(100_000_000))
# print(f"List size: {sys.getsizeof(large_list) / (1024**2):.2f} MB")

# 使用itertools处理同样规模的数据,内存占用极小
# 只取前10个,但它能够处理理论上无限的序列
lazy_numbers = itertools.islice(itertools.count(0), 100_000_000)
# lazy_numbers本身只是一个迭代器对象,内存占用极小
print(f"Iterator object size: {sys.getsizeof(lazy_numbers)} bytes")

# 只有在迭代时才会生成元素
sum_of_first_ten = sum(itertools.islice(itertools.count(0), 10))
print(f"Sum of first ten: {sum_of_first_ten}") # 输出: 45

从上面的代码片段就能看出,

itertools
返回的迭代器对象本身只占用极少的内存,它存储的只是生成下一个元素所需的状态信息,而不是所有的元素。这对于处理日志文件、网络流、大型数据库查询结果等场景至关重要,因为这些数据源往往是流式的,或者其整体大小远超可用内存。

此外,

itertools
模块中的函数都是用C语言实现的,这意味着它们的执行效率非常高,通常比纯Python实现的等效循环要快得多。在需要进行大量组合、排列计算的算法问题中,或者在需要对数据流进行复杂转换和过滤时,这种底层的性能优势能够显著缩短程序的运行时间。因此,对于任何追求效率和内存优化的Python开发者来说,深入理解和掌握
itertools
都是一项基本功。

如何利用
itertools
优雅地生成组合与排列?

在需要生成数据的所有可能组合或排列时,

itertools
模块简直是神来之笔,它提供了
product
permutations
combinations
combinations_with_replacement
这四个核心函数,让我们能够以极其简洁和高效的方式完成这些任务,而无需手写复杂的递归或多层循环。

我们来逐一看看它们是如何工作的:

  1. *`itertools.product(iterables, repeat=1)

    :笛卡尔积** 这个函数用来生成多个可迭代对象中所有元素的笛卡尔积。你可以把它想象成多层嵌套循环的扁平化版本。
    repeat`参数可以用来重复单个可迭代对象,这在生成固定长度的所有可能序列时非常有用。

    场景示例: 假设你需要生成所有两位数的密码,其中第一位是字母'A'或'B',第二位是数字'1'或'2'。

    dmSOBC SHOP网店系统
    dmSOBC SHOP网店系统

    dmSOBC SHOP网店系统由北京时代胜腾信息技术有限公司(http://www.webzhan.com)历时6个月开发完成,本着简单实用的理念,商城在功能上摒弃了外在装饰的一些辅助功能,尽可能的精简各项模块开发,做到有用的才开发,网店V1.0.0版本开发完成后得到了很多用户的使用并获得了好评,公司立即对网店进行升级,其中包括修正客户提出的一些意见和建议,现对广大用户提供免费试用版本,如您在使用

    下载
    import itertools
    
    first_chars = ['A', 'B']
    second_chars = ['1', '2']
    all_passwords = list(itertools.product(first_chars, second_chars))
    print(f"所有两位密码: {all_passwords}")
    # 输出: 所有两位密码: [('A', '1'), ('A', '2'), ('B', '1'), ('B', '2')]
    
    # 如果要生成所有由'0'和'1'组成的三位二进制数
    binary_digits = ['0', '1']
    three_bit_numbers = list(itertools.product(binary_digits, repeat=3))
    print(f"所有三位二进制数: {three_bit_numbers}")
    # 输出: 所有三位二进制数: [('0', '0', '0'), ('0', '0', '1'), ..., ('1', '1', '1')]

    它在生成所有可能的状态、配置组合或在暴力破解(当然是合法的测试场景)中非常有用。

  2. itertools.permutations(iterable, r=None)
    :排列 这个函数用于生成
    iterable
    中所有长度为
    r
    的排列。排列强调元素的顺序,即
    ('A', 'B')
    ('B', 'A')
    被认为是不同的排列。如果
    r
    None
    ,则生成所有可能长度的排列。

    场景示例: 假设你有三位运动员A、B、C,需要找出他们获得金牌和银牌的所有可能组合(顺序很重要)。

    athletes = ['A', 'B', 'C']
    gold_silver_permutations = list(itertools.permutations(athletes, 2))
    print(f"金银牌排列: {gold_silver_permutations}")
    # 输出: 金银牌排列: [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

    这在需要考虑顺序的场景,比如任务调度、密码学中的序列生成等,非常实用。

  3. itertools.combinations(iterable, r)
    :组合 这个函数生成
    iterable
    中所有长度为
    r
    的组合。组合强调元素的集合不考虑顺序,即
    ('A', 'B')
    ('B', 'A')
    被认为是相同的组合,
    combinations
    只会输出其中一个。

    场景示例: 从三位运动员A、B、C中选出两位参加接力赛,不考虑出场顺序。

    athletes = ['A', 'B', 'C']
    relay_teams = list(itertools.combinations(athletes, 2))
    print(f"接力赛队伍组合: {relay_teams}")
    # 输出: 接力赛队伍组合: [('A', 'B'), ('A', 'C'), ('B', 'C')]

    这在需要从一组选项中选择子集(如抽奖、选课、构建投资组合)时非常有用。

  4. itertools.combinations_with_replacement(iterable, r)
    :带重复的组合 这个函数生成
    iterable
    中所有长度为
    r
    的带重复元素的组合。同样不考虑顺序,但允许元素被选择多次。

    场景示例: 你有三种口味的冰淇淋(草莓、巧克力、香草),想买两勺,允许选择相同口味。

    flavors = ['草莓', '巧克力', '香草']
    ice_cream_scoops = list(itertools.combinations_with_replacement(flavors, 2))
    print(f"冰淇淋勺组合: {ice_cream_scoops}")
    # 输出: 冰淇淋勺组合: [('草莓', '草莓'), ('草莓', '巧克力'), ('草莓', '香草'), ('巧克力', '巧克力'), ('巧克力', '香草'), ('香草', '香草')]

    这在一些概率统计、游戏设计(如掷骰子结果)或资源分配问题中会派上用场。

通过这些函数,我们可以避免编写复杂的循环和递归逻辑,让代码更清晰、更易读,同时还能享受到C语言级别的性能优势。它们是解决各种组合优化、穷举搜索问题的利器。

除了基础功能,
itertools
还有哪些不为人知但极其实用的“小技巧”?

除了那些显而易见的组合、排列和无限序列生成器,

itertools
里还藏着一些非常精巧且在特定场景下能大幅提升代码优雅度和效率的“小技巧”。它们可能不那么直观,但一旦掌握,你会发现它们能解决很多看似复杂的问题。

  1. groupby(iterable, key=None)
    :按键分组 这绝对是
    itertools
    中最具魔力的函数之一,但它有一个“陷阱”:它只对连续的相同元素进行分组。这意味着如果你想对整个数据集进行分组,你通常需要先对其进行排序。一旦理解了这一点,它的威力就显现出来了。

    实用场景: 想象你有一份日志文件,记录了不同用户的操作,你想按用户ID将他们的操作分组。

    import itertools
    
    log_entries = [
        {'user': 'Alice', 'action': 'login'},
        {'user': 'Bob', 'action': 'view_page'},
        {'user': 'Alice', 'action': 'add_item'},
        {'user': 'Alice', 'action': 'logout'},
        {'user': 'Bob', 'action': 'purchase'}
    ]
    
    # groupby要求数据是预先排序的,否则它只会对连续的相同key进行分组
    log_entries.sort(key=lambda x: x['user'])
    # 排序后: [{'user': 'Alice', ...}, {'user': 'Alice', ...}, {'user': 'Alice', ...}, {'user': 'Bob', ...}, {'user': 'Bob', ...}]
    
    print("按用户分组的日志:")
    for user_id, group in itertools.groupby(log_entries, key=lambda x: x['user']):
        print(f"  用户: {user_id}")
        for entry in group:
            print(f"    - {entry['action']}")
    # 输出:
    #   用户: Alice
    #     - login
    #     - add_item
    #     - logout
    #   用户: Bob
    #     - view_page
    #     - purchase

    groupby
    在数据分析、报告生成、日志处理等场景中,能以非常Pythonic的方式实现复杂的分组逻辑。

  2. tee(iterable, n=2)
    :复制迭代器 你有没有遇到过这样的情况:你需要对一个迭代器进行多次遍历,但迭代器一旦被消耗就不能再次使用了?
    tee
    就是来解决这个问题的。它能将一个迭代器“分叉”成
    n
    个独立的迭代器,每个都可以独立地被遍历。

    实用场景: 你从一个网络流中读取数据,需要同时计算数据的总和以及平均值,但不想重新读取数据。

    data_stream = (x for x in range(10)) # 模拟一个只能遍历一次的迭代器
    
    # 使用tee复制迭代器
    iter1, iter2 = itertools.tee(data_stream, 2)
    
    total_sum = sum(iter1)
    count = 0
    for _ in iter2: # iter2是独立的,可以再次遍历
        count += 1
    
    print(f"总和: {total_sum}, 元素个数: {count}")
    # 输出: 总和: 45, 元素个数: 10

    这对于需要进行多路处理或缓存迭代器内容的场景非常有用,避免了将整个迭代器转换为列表的内存开销。

  3. chain.from_iterable(iterable)
    :扁平化嵌套迭代器
    itertools.chain()
    我们知道可以连接多个可迭代对象。而
    chain.from_iterable()
    则是它的一个类方法,专门用于扁平化一个包含多个可迭代对象的迭代器。

    实用场景: 你有一个列表的列表,或者一个生成器的生成器,想把它们的所有元素合并成一个单一的序列。

    list_of_lists = [[1, 2, 3], ['a', 'b'], [True, False]]
    flattened_list = list(itertools.chain.from_iterable(list_of_lists))
    print(f"扁平化列表: {flattened_list}")
    # 输出: 扁平化列表: [1, 2, 3, 'a', 'b', True, False]
    
    # 也可以处理生成器
    def gen_numbers():
        yield [1, 2]
        yield [3, 4]
    
    flattened_gen = list(itertools.chain.from_iterable(gen_

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

401

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

619

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

354

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

259

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

603

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

530

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

645

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

603

2023.09.22

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号