2012-12-27 45 views
1

我創建了一個有效地從52張牌組中隨機發牌的類。然後我寫了幾行來模擬52Ks的100K模擬,因爲我想知道分發是否正確執行。當我這樣做時,我意識到它運行SIM卡需要87秒。對我來說這似乎很長時間。有人可以指出#2中的一些東西可能會讓它變得如此緩慢嗎?優化類模擬代碼?

import time 
import random as rand 
import numpy as np 
class PlayingCard: 
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A'] 
    suits = ['Spades', 'Hearts', 'Clubs', 'Diamonds'] 
    def __init__(self, rank = None, suit = None): 
     if rank is None: self.rank = PlayingCard.ranks[rand.randint(0,12)] 
     elif rank in PlayingCard.ranks: self.rank = rank 
     else: raise NameError('Invalid rank') 

     if suit is None: self.suit = PlayingCard.suits[rand.randint(0,3)] 
     elif suit in PlayingCard.suits: self.suit = suit 
     else: raise NameError('Invalid suit') 

    def identity(self): 
     return (self.rank,self.suit) 
#2 
start = time.clock() 

deck = zip(PlayingCard.ranks*4,PlayingCard.suits*13) 
mat = [[PlayingCard().identity() for x in range(52)] for y in range(100000)] 
res = [[(y.count(x)/52.0) for x in deck] for y in mat] 
mean = [np.mean([res[y][x] for y in range(len(res))]) for x in range(52)] 

end = time.clock() - start 
print end 
+3

87秒實例超過500億個對象(然後通過名單做超過500億次搜索)似乎並不*那*瘋了。 – Amber

+0

創建'5,200,000'類實例不會很快。擺脫你的課堂。 – Blender

回答

4

你爲什麼不計算抽獎數量?它的方式更快:

import pprint 
import random 

from collections import defaultdict 

ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] 
suits = ['Spades', 'Hearts', 'Clubs', 'Diamonds'] 

deck = zip(ranks * 4, suits * 13) 

def test(trials=100000): 
    draws = defaultdict(int) 

    for i in range(trials): 
     draws[random.choice(deck)] += 1 

    return {card: float(value)/trials for card, value in draws.iteritems()} 


pprint.pprint(test(100000)) 

這將運行在約0.6秒對我來說:

{('10', 'Clubs'): 0.01961, 
('10', 'Diamonds'): 0.01897, 
('10', 'Hearts'): 0.0196, 
('10', 'Spades'): 0.01902, 
('2', 'Clubs'): 0.01953, 
('2', 'Diamonds'): 0.0201, 
('2', 'Hearts'): 0.01889, 
('2', 'Spades'): 0.01891, 
('3', 'Clubs'): 0.01943, 
('3', 'Diamonds'): 0.0198, 
('3', 'Hearts'): 0.01893, 
('3', 'Spades'): 0.01953, 
('4', 'Clubs'): 0.01973, 
('4', 'Diamonds'): 0.01946, 
('4', 'Hearts'): 0.01822, 
('4', 'Spades'): 0.01931, 
('5', 'Clubs'): 0.01845, 
('5', 'Diamonds'): 0.01956, 
('5', 'Hearts'): 0.01978, 
('5', 'Spades'): 0.01943, 
('6', 'Clubs'): 0.01852, 
('6', 'Diamonds'): 0.01903, 
('6', 'Hearts'): 0.01928, 
('6', 'Spades'): 0.01848, 
('7', 'Clubs'): 0.0195, 
('7', 'Diamonds'): 0.01881, 
('7', 'Hearts'): 0.0194, 
('7', 'Spades'): 0.01926, 
('8', 'Clubs'): 0.01946, 
('8', 'Diamonds'): 0.0188, 
('8', 'Hearts'): 0.01985, 
('8', 'Spades'): 0.01875, 
('9', 'Clubs'): 0.01914, 
('9', 'Diamonds'): 0.01908, 
('9', 'Hearts'): 0.01937, 
('9', 'Spades'): 0.01838, 
('A', 'Clubs'): 0.01935, 
('A', 'Diamonds'): 0.01843, 
('A', 'Hearts'): 0.01957, 
('A', 'Spades'): 0.01852, 
('J', 'Clubs'): 0.01992, 
('J', 'Diamonds'): 0.01933, 
('J', 'Hearts'): 0.01881, 
('J', 'Spades'): 0.01946, 
('K', 'Clubs'): 0.01932, 
('K', 'Diamonds'): 0.01845, 
('K', 'Hearts'): 0.01935, 
('K', 'Spades'): 0.02015, 
('Q', 'Clubs'): 0.0189, 
('Q', 'Diamonds'): 0.01942, 
('Q', 'Hearts'): 0.01977, 
('Q', 'Spades'): 0.01988} 
+0

@ Blender.By生成器你的意思是「random.choice」?我之前讀過一些關於發生器功能的東西,但並沒有真正理解它。這是一個例子嗎? – cdelsola

+0

另外,我對OOP不是很熟悉。除了爲類編寫的方法和屬性賦值之外,是否實例化類本身很慢? – cdelsola

+2

@ user1816858:對不起,我刪除了原來的答案。當你做'[i for range in(10)]'時,你創建一個包含10個元素的列表。當你做'(我爲我在範圍(10))',你立即創建一個發電機。生成器只會在請求一個項目時產生一個項目,所以您不會在內存中創建一個巨大的列表。 – Blender