別再寫嵌套 for 循環了!Python 自帶的 itertools,小白也能十分鐘學會
你是不是也寫過這樣的代碼?
- 想合并3個列表,手動寫list1 + list2 + list3,結果中間漏了一個;
- 想生成“顏色+尺寸”的所有搭配(紅S、紅M、藍S...),寫了兩層for循環,嵌套得像繞迷宮;
- 想給列表元素加序號,又要定義i=0,再寫i +=1,代碼又長又丑。
其實Python早就自帶了一個“循環救星”——itertools模塊,不用裝,拿過來就能用,能把嵌套循環、手動排序、合并列表這些麻煩事,一行代碼搞定。今天就用最白話的方式,帶小白和技術渣吃透它最常用的8個功能,學完就能用!

一、先搞懂:itertools是啥?為啥新手也該用它?
不用記復雜概念!記住3個關鍵點:
- 不用裝:是Python自帶的,Import就能用,不用pip install;
- 省內存:它不一次性把所有數據裝到內存里(比如生成100萬個數,不會占100萬個數的內存),用的時候才生成,跑大數據也不卡;
- 少寫循環:以前要寫3行嵌套for循環的事,用它一行就能搞定,代碼少了,bug也少了。
簡單說,itertools就是“幫你偷懶的工具”,專門解決“處理列表/序列”的麻煩事。
二、八個必學函數:從“麻煩循環”到“一行代碼”
每個函數都按“解決啥問題→代碼示例→結果解釋→小提醒”來講,新手跟著抄代碼就行。
1. count:給數據自動加序號(不用手動i+=1)
解決啥問題?
給列表元素加排名/序號,比如“1. Alice,2. Bob”,不用再寫i=1然后i +=1。
代碼示例:
import itertools # 先導入,這行必須有
# 要加序號的列表
names = ["Alice", "Bob", "Charlie"]
# 用count(1):從1開始計數,配合zip把序號和名字綁一起
indexed_names = zip(itertools.count(1), names)
# 打印結果
for idx, name in indexed_names:
print(f"{idx}. {name}")結果:
1. Alice
2. Bob
3. Charlie小提醒:
- itertools.count(1)里的1是“起始數”,想從10開始就寫count(10);
- 它會一直數下去,所以要配合zip(列表結束就停),別單獨用,不然會無限循環。
2. chain:合并多個列表(不用手動拼接)
解決啥問題?
想把3個、4個列表合并成1個,不用寫list1 + list2 + list3,尤其列表多的時候更方便。
代碼示例:
import itertools
# 3個要合并的列表(甚至可以是元組、字符串)
list1 = [1, 2, 3]
list2 = ["a", "b"]
list3 = (4, 5) # 元組也能合并
# 一行合并
combined = list(itertools.chain(list1, list2, list3))
print(combined)結果:
[1, 2, 3, 'a', 'b', 4, 5]小提醒:
- 比list1 + list2好在哪?如果列表很多(比如10個),chain不用寫一堆+,直接把所有列表放進去就行;
- 最后要轉成list()才能看到結果,不然是個迭代器(新手不用管迭代器,記住加list()就行)。
3. groupby:按規則分組(不用寫循環判斷)
解決啥問題?
把列表按某個規則分組,比如“按單詞長度分組”“按數字大小分組”,不用寫if-else循環。
代碼示例:按單詞長度分組
import itertools
# 要分組的單詞
words = ["cat", "dog", "elephant", "bird", "ant"]
# 第一步:先按長度排序!groupby只認連續的相同元素(重點坑?。?sorted_words = sorted(words, key=lambda x: len(x)) # 按長度排序
# 第二步:按長度分組
grouped = itertools.groupby(sorted_words, key=lambda x: len(x))
# 打印結果
for length, group in grouped:
print(f"長度{length}的單詞:{list(group)}")結果:
長度3的單詞:['cat', 'dog', 'ant']
長度4的單詞:['bird']
長度8的單詞:['elephant']小提醒:
- 新手必踩坑:groupby只會給“連續的相同元素”分組!如果不先排序(比如words沒排序),會把相同長度的單詞分成多組,一定要先sorted;
- key=lambda x: len(x)就是“按單詞長度當分組依據”,想按其他規則改這里就行(比如按首字母key=lambda x: x[0])。
4. product:生成所有組合(代替嵌套for循環)
解決啥問題?
想生成“兩個列表所有可能的搭配”,比如“顏色(紅、藍)+尺寸(S、M)”,不用寫兩層for循環。
代碼示例:生成顏色+尺寸的所有搭配
import itertools
# 兩個要搭配的列表
colors = ["red", "blue"]
sizes = ["S", "M", "L"]
# 一行生成所有組合
all_combos = list(itertools.product(colors, sizes))
print(all_combos)結果:
[('red', 'S'), ('red', 'M'), ('red', 'L'), ('blue', 'S'), ('blue', 'M'), ('blue', 'L')]小提醒:
? 相當于“嵌套for循環”的簡化版,比如原來要寫:
for color in colors:
for size in sizes:
print((color, size))現在一行product就搞定;
? 想讓一個列表自搭配(比如0和1生成3位二進制),用repeat:itertools.product([0,1], repeat=3),結果就是[(0,0,0), (0,0,1), ..., (1,1,1)]。
5. combinations:選“不重復的組合”(比如抽獎)
解決啥問題?
從列表里選幾個元素,不考慮順序,也不重復選(比如從5個人里選2個抽獎,AB和BA算一個)。
代碼示例:從4個人里選2個抽獎
import itertools
# 候選人
people = ["A", "B", "C", "D"]
# 選2個,不重復,不考慮順序
lottery = list(itertools.combinations(people, 2))
print(lottery)結果:
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]小提醒:
- 和product的區別:product考慮順序(AB和BA都有),combinations不考慮(只有AB);
- 第二個參數2是“選幾個元素”,想選3個就寫3。
6. zip_longest:合并不同長度的列表(不會截斷)
解決啥問題?
用普通zip合并列表時,短的列表結束了就會截斷(比如[1,2]和[3,4,5],zip會只合并到(2,4)),zip_longest能把短的補滿(比如補“N/A”)。
代碼示例:合并名字和分數(名字比分數多1個)
import itertools
names = ["Alice", "Bob", "Charlie"] # 3個名字
scores = [85, 92] # 2個分數,少1個
# 用fillvalue補缺失的分數
result = list(itertools.zip_longest(names, scores, fillvalue="沒分數"))
print(result)結果:
[('Alice', 85), ('Bob', 92), ('Charlie', '沒分數')]小提醒:
- fillvalue是“補什么值”,可以是數字、字符串,比如缺的分數補0就寫fillvalue=0;
- 普通zip會截斷,zip_longest會補滿,根據需求選。
7. islice:切片(比列表切片更靈活)
解決啥問題?
想從列表/迭代器里“取前N個”“跳過前幾個再取”,不用手動寫循環,尤其對不能直接切片的對象(比如生成器)更有用。
代碼示例:
import itertools
# 一個長列表(比如100個元素,這里用range模擬)
big_list = range(100)
# 1. 取前5個:islice(對象, 結束位置)
first5 = list(itertools.islice(big_list, 5))
print("前5個:", first5)
# 2. 跳過前3個,取接下來的4個:islice(對象, 起始, 結束)
skip3_take4 = list(itertools.islice(big_list, 3, 7))
print("跳過3取4個:", skip3_take4)
# 3. 每隔2個取一個(步長2):islice(對象, 起始, 結束, 步長)
every2 = list(itertools.islice(big_list, 0, 10, 2))
print("每隔2個取一個:", every2)結果:
前5個: [0, 1, 2, 3, 4]
跳過3取4個: [3, 4, 5, 6]
每隔2個取一個: [0, 2, 4, 6, 8]小提醒:
- 和列表切片big_list[3:7]的區別:islice能處理不能切片的對象(比如itertools.count()生成的迭代器);
- 不支持負索引(比如不能寫islice(big_list, -5)),新手記住用正整數就行。
8. accumulate:計算累積值(比如累加、累乘)
解決啥問題?
想算“累加和”“累乘積”“運行最大值”,不用寫循環手動加/乘。
代碼示例:
import itertools
import operator # 用來做累乘,新手不用管,導入就行
# 原始數據
data = [1, 2, 3, 4, 5]
# 1. 累加(默認就是加)
running_sum = list(itertools.accumulate(data))
print("累加和:", running_sum)
# 2. 累乘(用operator.mul當運算規則)
running_prod = list(itertools.accumulate(data, operator.mul))
print("累乘積:", running_prod)
# 3. 運行最大值(用max當規則)
prices = [3, 1, 4, 1, 5, 9]
running_max = list(itertools.accumulate(prices, max))
print("運行最大值:", running_max)結果:
累加和: [1, 3, 6, 10, 15] # 1→1+2=3→3+3=6→...
累乘積: [1, 2, 6, 24, 120] # 1→1×2=2→2×3=6→...
運行最大值: [3, 3, 4, 4, 5, 9] # 每次取當前最大的數小提醒:除了加、乘、max,還能自定義運算(比如每次加10),新手先掌握加、乘、max就行。
三、新手避坑指南(3個最容易錯的點)
- groupby必須先排序:再強調一次!groupby只給“連續的相同元素”分組,沒排序的話,相同規則的元素會被分成多組。比如words = ["cat", "elephant", "dog"]不排序,按長度分組會把“cat”和“dog”(都是3個字母)分成兩組,排序后才會放一起。
- 迭代器要轉成list才能看結果:itertools的函數返回的是“迭代器”(不是列表),所以要加list()才能打印出具體內容,比如list(itertools.chain(list1, list2)),不然打印的是<itertools.chain object at 0x0000...>,新手會以為出錯了。
- count和cycle別單獨用:count()會無限計數,cycle()會無限循環,單獨用會讓程序卡死,一定要配合zip或islice限制長度,比如zip(itertools.count(), names)(names結束就停)。
四、最后:新手怎么練?
- 抄代碼改參數:把上面的示例代碼抄到自己的Python里,改改參數(比如count從10開始,product加個新顏色),看結果怎么變;
- 改自己的舊代碼:找出以前寫過的嵌套for循環、手動合并列表的代碼,試著用itertools重寫,比如把“兩層for循環生成組合”改成product;
- 記常用場景:不用記所有函數,先記住“合并列表用chain”“生成組合用product”“分組用groupby”“加序號用count”,這些是新手最常用的。
itertools不是“高深技術”,而是幫新手偷懶的工具——代碼寫得少,bug就少,效率還高。





























