列出所有可能的 5 张牌扑克
Making a list of all possible 5 card poker
我正在尝试列出所有可能的 5 张扑克手牌以用于某些计算(这可能会很慢,但最好是有点快)。现在要获取列表,我编写了以下代码:
import itertools
# All possible Cards:
cards = ['2s', '2h', '2d', '2c', '3s', '3h', '3d', '3c', '4s', '4h', '4d', '4c', '5s', '5h', '5d', '5c', '6s', '6h', '6d', '6c', '7s', '7h', '7d', '7c', '8s', '8h', '8d', '8c', '9s', '9h', '9d', '9c', 'Ts', 'Th', 'Td', 'Tc', 'Js', 'Jh', 'Jd', 'Jc', 'Qs', 'Qh', 'Qd', 'Qc', 'Ks', 'Kh', 'Kd', 'Kc', 'As', 'Ah', 'Ad', 'Ac']
hands = []
# Collect all non-trivial cartesian products
for element in itertools.product(cards,cards,cards,cards,cards):
c1,c2,c3,c4,c5 = element
if c1 != c2 or c1!=c3 or c1!=c4 or c1!=c5 or c2 != c3 or c2 != c4 or c2 != c5 or c3 != c4 or c3 != c5 or c4 != c5:
hands.append([c1,c2,c3,c4,c5])
# Sort all elements and delete duplicates
for x in hands:
x.sort()
hands = [tuple(x) for x in hands]
hands = list(set(hands))
# Convert hands back to a list
hands = [list(x) for x in hands]
# Verify result
print(str(len(hands)))
但这在完成之前就用完了内存(超过 11 GB 的 RAM)。我正在尝试使用该列表,以便在我尝试将 2 只手放在一起时,我可以针对所有可能的手牌进行详尽测试。
有谁知道我该如何改进这段代码?
您正在生成 ~52^5 = ~3.8 亿手牌,并尝试对它们进行排序。这将占用大量内存。您需要修复逻辑以确保每只手上的每个元素都是唯一的。您当前拥有的只会删除它们都相同的那些。
c1, c2, c3, c4, c5 = "2s", "2s", "2s", "2s", "3s"
print(c1 != c2 or c1!=c3 or c1!=c4 or c1!=c5 or c2 != c3 or c2 != c4 or c2 != c5 or c3 != c4 or c3 != c5 or c4 != c5)
>>>True
您可以将所有的 or 替换为 and,或者您可以只测试元素的集合是否等于元素本身,这将消除重复的手。
c1, c2, c3, c4, c5 = "2s", "2s", "2s", "2s", "3s"
print(list(set([c1,c2,c3,c4,c5])).sort() == [c1,c2,c3,c4,c5].sort())
>>>False
c1, c2, c3, c4, c5 = "2s", "3s", "4s", "5s", "6s"
print(list(set([c1,c2,c3,c4,c5])).sort() == [c1,c2,c3,c4,c5].sort())
>>>True
这会将手数减少到 52 选择 5 = ~260 万,这更易于管理。
首先,您尝试创建的函数已经存在:itertools.combinations
。其次,尝试构建您的代码,以便您可以遍历所有可能的手牌,而无需同时将它们全部放入内存。
这是一个简短的程序,它打印所有可能的手牌,删除了重复的手牌,但从不创建所有可能手牌的内存列表:
import itertools
cards = [''.join(x) for x in itertools.product('23456789TJQKA', 'shdc')]
for hand in itertools.combinations(cards, 5):
print (hand)
如果您确实需要将整个列表存储在内存中,请尝试:
import itertools
cards = [''.join(x) for x in itertools.product('23456789TJQKA', 'shdc')]
big_list = list(itertools.combinations(cards, 5))
print len(big_list)
Python 实际上附带了一些电池,用于组合。
Here is the function 这会为你做到这一点。
cards = ['2s', '2h', '2d', '2c', '3s', '3h', '3d', '3c', '4s', '4h', '4d', '4c', '5s', '5h', '5d', '5c', '6s', '6h', '6d', '6c', '7s', '7h', '7d', '7c', '8s', '8h', '8d', '8c', '9s', '9h', '9d', '9c', 'Ts', 'Th', 'Td', 'Tc', 'Js', 'Jh', 'Jd', 'Jc', 'Qs', 'Qh', 'Qd', 'Qc', 'Ks', 'Kh', 'Kd', 'Kc', 'As', 'Ah', 'Ad', 'Ac']
hands = itertools.combinations(cards, 5)
for hand in hands:
print(hand)
我正在尝试列出所有可能的 5 张扑克手牌以用于某些计算(这可能会很慢,但最好是有点快)。现在要获取列表,我编写了以下代码:
import itertools
# All possible Cards:
cards = ['2s', '2h', '2d', '2c', '3s', '3h', '3d', '3c', '4s', '4h', '4d', '4c', '5s', '5h', '5d', '5c', '6s', '6h', '6d', '6c', '7s', '7h', '7d', '7c', '8s', '8h', '8d', '8c', '9s', '9h', '9d', '9c', 'Ts', 'Th', 'Td', 'Tc', 'Js', 'Jh', 'Jd', 'Jc', 'Qs', 'Qh', 'Qd', 'Qc', 'Ks', 'Kh', 'Kd', 'Kc', 'As', 'Ah', 'Ad', 'Ac']
hands = []
# Collect all non-trivial cartesian products
for element in itertools.product(cards,cards,cards,cards,cards):
c1,c2,c3,c4,c5 = element
if c1 != c2 or c1!=c3 or c1!=c4 or c1!=c5 or c2 != c3 or c2 != c4 or c2 != c5 or c3 != c4 or c3 != c5 or c4 != c5:
hands.append([c1,c2,c3,c4,c5])
# Sort all elements and delete duplicates
for x in hands:
x.sort()
hands = [tuple(x) for x in hands]
hands = list(set(hands))
# Convert hands back to a list
hands = [list(x) for x in hands]
# Verify result
print(str(len(hands)))
但这在完成之前就用完了内存(超过 11 GB 的 RAM)。我正在尝试使用该列表,以便在我尝试将 2 只手放在一起时,我可以针对所有可能的手牌进行详尽测试。
有谁知道我该如何改进这段代码?
您正在生成 ~52^5 = ~3.8 亿手牌,并尝试对它们进行排序。这将占用大量内存。您需要修复逻辑以确保每只手上的每个元素都是唯一的。您当前拥有的只会删除它们都相同的那些。
c1, c2, c3, c4, c5 = "2s", "2s", "2s", "2s", "3s"
print(c1 != c2 or c1!=c3 or c1!=c4 or c1!=c5 or c2 != c3 or c2 != c4 or c2 != c5 or c3 != c4 or c3 != c5 or c4 != c5)
>>>True
您可以将所有的 or 替换为 and,或者您可以只测试元素的集合是否等于元素本身,这将消除重复的手。
c1, c2, c3, c4, c5 = "2s", "2s", "2s", "2s", "3s"
print(list(set([c1,c2,c3,c4,c5])).sort() == [c1,c2,c3,c4,c5].sort())
>>>False
c1, c2, c3, c4, c5 = "2s", "3s", "4s", "5s", "6s"
print(list(set([c1,c2,c3,c4,c5])).sort() == [c1,c2,c3,c4,c5].sort())
>>>True
这会将手数减少到 52 选择 5 = ~260 万,这更易于管理。
首先,您尝试创建的函数已经存在:itertools.combinations
。其次,尝试构建您的代码,以便您可以遍历所有可能的手牌,而无需同时将它们全部放入内存。
这是一个简短的程序,它打印所有可能的手牌,删除了重复的手牌,但从不创建所有可能手牌的内存列表:
import itertools
cards = [''.join(x) for x in itertools.product('23456789TJQKA', 'shdc')]
for hand in itertools.combinations(cards, 5):
print (hand)
如果您确实需要将整个列表存储在内存中,请尝试:
import itertools
cards = [''.join(x) for x in itertools.product('23456789TJQKA', 'shdc')]
big_list = list(itertools.combinations(cards, 5))
print len(big_list)
Python 实际上附带了一些电池,用于组合。
Here is the function 这会为你做到这一点。
cards = ['2s', '2h', '2d', '2c', '3s', '3h', '3d', '3c', '4s', '4h', '4d', '4c', '5s', '5h', '5d', '5c', '6s', '6h', '6d', '6c', '7s', '7h', '7d', '7c', '8s', '8h', '8d', '8c', '9s', '9h', '9d', '9c', 'Ts', 'Th', 'Td', 'Tc', 'Js', 'Jh', 'Jd', 'Jc', 'Qs', 'Qh', 'Qd', 'Qc', 'Ks', 'Kh', 'Kd', 'Kc', 'As', 'Ah', 'Ad', 'Ac']
hands = itertools.combinations(cards, 5)
for hand in hands:
print(hand)