Python中zip()搭配itertools.islice运行结果不符合预期问题求解
问题原因分析
问题根本不是zip()函数的逻辑错误,而是itertools返回的迭代器的共享状态特性导致的
- Python中
itertools模块返回的所有对象都是一次性消耗迭代器,遍历过程中只会向前移动指针,不会重置位置,也不会自动保存副本。你代码里的cards = it.product(ranks,suits)本身就是迭代器,后续所有it.islice操作都共享同一个cards的指针,没有独立快照。 - 你往
l里添加的5个it.islice(cards,2)对象,没有立刻执行取值,只是绑定了同一个cards迭代器。直到执行list(zip(*l))时,才会真正开始遍历取值。
zip(*l)的实际执行流程:zip每次会按顺序从传入的5个islice对象中各取1个元素,直到任意一个islice耗尽:
- 第一轮取值:依次从5个
islice各取1个元素,cards指针从0走到4,得到第一个元组:(('A', 'H'), ('A', 'D'), ('A', 'C'), ('A', 'S'), ('K', 'H')) - 第二轮取值:再次依次从5个
islice各取1个元素,cards指针从5走到9,每个islice都取满了2个元素全部耗尽,得到第二个元组:(('K', 'D'), ('K', 'C'), ('K', 'S'), ('Q', 'H'), ('Q', 'D')) - 没有更多元素,
zip结束,最终输出就是你看到的实际结果。
修正方案
如果你要得到预期的输出,需要每次调用islice后立刻将结果转为列表,提前固化当前取到的2个元素,避免后续共享指针的影响:
import itertools as it ranks = ['A', 'K', 'Q', 'J', '10', '9', '8', '7', '6', '5', '4', '3', '2'] suits = ['H', 'D', 'C', 'S'] cards = it.product(ranks,suits) l = [] for i in range(5): # 立刻转列表固化当前取值,不再共享迭代器指针 l.append(list(it.islice(cards,2))) print(list(zip(*l)))
运行后输出就和你的预期完全一致。
内容的提问来源于stack exchange,提问作者shady
相关产品推荐
相关产品推荐

