找到你要的答案

Q:Check string in list for multiple occurrence

Q:检查多个列表中的字符串

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.

我试图找出下面的扑克手是同花顺:

在第一种情况下,我分析5卡。如果所有这5套衣服都是相同的(即C D S),即只有一套合适的话,那么同花顺是真实的。做工精细。

a=['AC', '3H', 'TD', '9C', 'KD']
flush = len({suit for _, suit in a}) ==1 #false

然而在现实中通常有7张牌。2是由球员和5是在桌子上。这里有点复杂。我如何检查是否有诉讼正好发生5次?

b=['AC', '3H', 'TD', '9C', 'KD', '7H', '5S']
flush = ?

速度是非常重要的因为这是一个的MonteCarlo模拟内循环的一部分,所以这应该是一一套如果可能的话。

answer1: 回答1:

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

您可以使用计数和MAX找到…嗯,任何衣服的最大计数,看看它是否至少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

但这将循环列表的每个元素的西装,给它O(N 2)的复杂性。也许不是太坏,考虑到N只是7,但仍然。或使用collections.counter。这应该快得多(O(N)),因为它使用字典来跟踪计数。

>>> max(collections.Counter((s for _, s in b)).values())
2
>>> collections.Counter((s for _, s in b)).most_common(1)
[('H', 2)]
answer2: 回答2:
list = ['AC', '3H', 'TD', '9C', 'KD']
substring='C'
print( len([s for s in list if substring in s]))
list = ['AC', '3H', 'TD', '9C', 'KD']
substring='C'
print( len([s for s in list if substring in s]))
answer3: 回答3:

If speed is the key, well, there are only 7 cards, 4 suits. That makes 16384 combinations. I would convert each combination to a number and make a lookup in a precomputed table using this number as an index.

CONV = dict(C=0, H=1, D=2, S=3)
def flush_table_index(cards):
    n = 0 
    for _, s in cards:
        n = n * 4 + CONV[s]
    return n

Edit: if-elif-elif instead of CONV would be quicker. Not a pretty or interesting code though.

如果速度是关键,那么,只有7张牌,4套。这使得16384个组合。我会把每一个数组合和使用该号码作为索引在一个预先计算的表进行查找。

CONV = dict(C=0, H=1, D=2, S=3)
def flush_table_index(cards):
    n = 0 
    for _, s in cards:
        n = n * 4 + CONV[s]
    return n

编辑:如果elif elif代替转换会更快。虽然不是一个漂亮或有趣的代码。

string  list  python-3.x  poker