4

我是 python 编程的新手(嗯,一般的编程),所以我真的希望有人可以帮助我使用内置的 itertools.combinations 函数。

我正在尝试从 52 张卡片(即 52 C 7)列表中创建所有可能组合 7 卡片组合的列表。

所以我的代码看起来像

>>> import itertools
>>> deck = [1,2,3,4,5...,52]
>>> list_1 = list(itertools.combinations(deck,2))
>>> list_1[5]
(1, 7)

工作到目前为止,直到我尝试 7 的组合

>>> all_possible_hands = list(itertools.combinations(deck,7))
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    all_possible_hands = list(itertools.combinations(deck,7))
MemoryError

可以为较小的数据集(52 C 2)创建该列表,但是当数字变大时,我得到一个 MemoryError,可能是 RAM 不足。我用谷歌搜索了 combine() 函数的工作原理,显然它输出了一个对象,我将其转换为一个列表。

当我没有 list() 时,控制台返回了一个内存地址(我相信)。

>>> all_possible_hands = itertools.combinations(deck,7)
>>> all_possible_hands
<itertools.combinations object at 0x02E63180>

我的问题是:内存地址是否包含我想要的数据,并且可以并且以某种方式将其转换为列表或其他东西,以便我可以访问列表中的各个元素?

谢谢你。任何见解将不胜感激。

4

2 回答 2

5

一副 52 张牌中有 133784560 张七张牌组合,您正在尝试创建一个包含 133784560 个元素的列表。Python 没有足够的内存来执行此操作,因此它崩溃了。

itertools.combinations返回一个迭代器。这就像一个列表,只是它只根据需要一次给你一个元素,而不是一次创建所有元素。这样可以节省内存。您是否可以从该迭代器中获得您想要的东西取决于您想要做什么。如果你只想打印每一个,你可以很容易地做到这一点:

for item in itertools.combinations(deck, 7):
     print item

你不能轻易做到的是得到一个特定的项目。没有直接等同list_l[5]于获得第五个元素的方法。您必须对迭代器进行 5 次迭代,或者使用itertools(如islice)中的其他工具。

于 2013-04-19T08:07:59.517 回答
1

该对象是一个迭代器,由生成器函数返回itertools.combinations。您可以通过迭代此对象来访问每个组合:

for hand in all_possible_hands:
     print hand

迭代器有助于避免一次将所有数据保存在内存中,但缺点是您只能访问每个项目一次。当你完成对对象的迭代时,它已经用尽了,你不能从中得到任何东西。此外,与通常的列表等不同,如果不迭代到最后,您将无法访问最后一项。

您也可以编写生成器函数。itertools文档中有示例。生成器函数应该有一个或多个yieldstatements而不是returnstatements

于 2013-04-19T08:07:00.340 回答