在python中使用HUGE列表

时间:2013-03-07 23:26:49

标签: python itertools poker

我如何管理一个包含1亿多字符串的庞大列表? 我怎样才能开始使用这么大的名单?

示例大型列表:

cards = [
            "2s","3s","4s","5s","6s","7s","8s","9s","10s","Js","Qs","Ks","As"
            "2h","3h","4h","5h","6h","7h","8h","9h","10h","Jh","Qh","Kh","Ah"
            "2d","3d","4d","5d","6d","7d","8d","9d","10d","Jd","Qd","Kd","Ad"
            "2c","3c","4c","5c","6c","7c","8c","9c","10c","Jc","Qc","Kc","Ac"
           ]

from itertools import combinations

cardsInHand = 7
hands = list(combinations(cards,  cardsInHand))

print str(len(hands)) + " hand combinations in texas holdem poker"

5 个答案:

答案 0 :(得分:7)

有大量的内存。 Python列表和字符串实际上合理有效,所以如果你有内存,它应该不是问题。

也就是说,如果您要存储的是专门的扑克手,那么您绝对可以提供更紧凑的表示形式。例如,您可以使用一个字节对每张卡进行编码,这意味着您只需要一个64位的int来存储整个手牌。然后,您可以将它们存储在NumPy数组中,这比Python列表更有效。

例如:

>>> cards_to_bytes = dict((card, num) for (num, card) in enumerate(cards))
>>> import numpy as np
>>> hands = np.zeros(133784560, dtype='7int8') # 133784560 == 52c7
>>> for num, hand in enumerate(itertools.combinations(cards, 7)):
...     hands[num] = [cards_to_bytes[card] for card in hand]

并加快了最后一行:hands[num] = map(cards_to_bytes.__getitem__, hand)

这只需要7 * 133784560 =〜1gb的内存......如果你将四张卡打包到每个字节中,这可能会被削减(我不知道这样做的语法在我的头顶......)< / p>

答案 1 :(得分:6)

如果您只想循环所有可能的牌来计算它们或找到具有特定属性的牌,那么无需将它们全部存储在内存中

您可以使用迭代器而不是转换为列表:

from itertools import combinations

cardsInHand = 7
hands = combinations(cards,  cardsInHand)

n = 0
for h in hands:
    n += 1
    # or do some other stuff here

print n, "hand combinations in texas holdem poker."
  

85900584德州扑克中的手牌组合。

答案 2 :(得分:1)

在编码花费的时间和运行代码所需的时间之间经常需要权衡。如果您只是想快速完成某项工作并且不希望它经常运行,那么您建议的方法就可以了。只需使列表变得庞大 - 如果你没有足够的RAM,你的系统将会流失虚拟内存,但你可能会比学习如何编写更复杂的解决方案更快地得到答案。

但是如果这是一个你希望定期使用的系统,你应该找出除了将所有东西都存储在RAM中之外的东西。 SQL数据库可能就是您想要的。它们可能非常复杂,但因为它们几乎无处不在,所以有很多优秀的教程。

您可能会看到像django这样记录良好的框架,它简化了通过ORM层对数据库的访问。

答案 3 :(得分:1)

另一个无内存选项允许您创建用于处理的数据流,但是您喜欢使用生成器。例如。

打印总手数:

sum (1 for x in combinations(cards, 7))

用手中的球杆打印手的数量:

sum (1 for x in combinations(cards, 7) if 'Ac' in x)

答案 4 :(得分:0)

我的公共域OneJoker库有一些方便的组合函数。它有一个Iterator类,可以为您提供有关组合集的信息,而无需存储它们甚至可以通过它们运行。例如:

  import onejoker as oj
  deck = oj.Sequence(52)
  deck.fill()

  hands = oj.Iterator(deck, 5)    # I want combinations of 5 cards out of that deck

  t = hands.total                 # How many are there?
  r = hands.rank("AcKsThAd3c")    # At what position will this hand appear?
  h = hands.hand_at(1000)         # What will the 1000th hand be?

  for h in hands.all():           # Do something with all of them
     dosomething(h)               

您可以使用Iterator.rank()函数将每只手减少到单个int,store 那些在紧凑数组中,然后使用Iterator.hand_at()按需生成它们。