2017-07-25 61 views
0

我正在嘗試製作所有可能的5張牌撲克手在一些計算中使用的列表(可能會很慢,但最好有點快)。現在獲取一個列表,我寫了下面的代碼:製作所有可能的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音樂會的RAM)前。我試圖使用該列表,以便當我嘗試將兩隻手對準另一隻手時,我可以對所有可能的手進行詳盡測試。

有誰知道我該如何讓這段代碼更好?

+0

無論何時你發現自己在想「做的所有可能的[事情]清單」,你應該首先考慮它是否是連半點合理的東西一切可能的[事情]內存或去通過所有可能的[事情]來完成你的任務。這通常是一個壞主意。 – user2357112

+0

你不需要所有可能的雙手列表來比較兩隻手相互對抗。 – user2357112

回答

1

首先,您嘗試創建的功能已存在: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) 
+0

此外,通過不使用字符串卡片保存一些內存;使用整數。 –

+0

是的。我無法決定提高這一點是否會把水弄髒。 –

1

您正在生產〜52^5 =〜380萬手,並試圖對它們進行分類。這將花費大量的記憶。您需要修正確保每隻手中每個元素都是唯一的邏輯。你目前擁有的只會刪除那些完全相同的東西。

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 

你可以要麼ANDS更換所有的口服補液鹽,或你可能只是測試,如果集合元素等於元素本身,這將消除與重複的手中。

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萬,這是更易於管理的。

2

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)