Search code examples
stringlistpython-3.xpoker

Check string in list for multiple occurrence


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.


Solution

  • 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)]