I'm trying to find out if the following poker hand is a flush:
In the first case I analyse 5 cards. A flush is true if there all the 5 suits are identical (C H D S), i.e. there is only one suit present. That works fine.
a=['AC', '3H', 'TD', '9C', 'KD']
flush = len({suit for _, suit in a}) ==1 #false
In reality however there are usually 7 cards. 2 are held by the player and 5 are on the table. Here it gets a bit more complicated. How can I check if any suit occurs exactly 5 times?
b=['AC', '3H', 'TD', '9C', 'KD', '7H', '5S']
flush = ?
Speed is very important as this is part of an inner loop of a montecarlo simulation, so this should probably be a one-liner if possible.
You could use count
and max
to find... well, the max count of any of the suits and see whether it's at least 5.
>>> b = ['AC', '3H', 'TD', '9C', 'KD', '7H', '5S']
>>> suits = [s for _, s in b]
>>> max(suits.count(s) for s in suits) >= 5
False
But this will loop the list of suits
for each element of that list, giving it O(n^2) complexity. Probably not too bad, considering that n
is just 7, but still. Or use collections.Counter
. This should be much faster (O(n)), as it uses a dictionary to keep track of the counts.
>>> max(collections.Counter((s for _, s in b)).values())
2
>>> collections.Counter((s for _, s in b)).most_common(1)
[('H', 2)]