检查字符串列表是否包含几个特定字符串对之一

Check if a list of strings contains one of several specific pairs of strings

这背后的动机是一个纸牌游戏,我想确定一手 5 张牌是否包含特定纸牌的某些组合,并将这些组合写在列表中。

更一般地说,假设我有一个字符串列表:

hand = ["apple", "apple", "banana", "cabbage", "durian"]

我还有一个元组列表:

combos = [
    ["apple", "banana"],
    ["banana", "lettuce"],
    ["banana", "pear"],
    ["cabbage", "cabbage"]
]
# code returns true because "apple" and "banana" are in the original list

我想确定“combos”中的任何一对字符串是否出现在我的原始列表中。由于同一个项目可以多次出现在我的原始列表中和作为有效的“组合”这一事实,这很复杂。

一种天真的方法是在我的原始列表中一次检查一个项目,找到包含该项目的每个组合,然后查看我是否有其他组合项目。我想知道是否有更简洁、优雅的方法来做到这一点。

也许是这样的:

def check_combos(combos, hand):
    for combo in combos:
        index = []
        for item in combo:
            if item in hand and hand.index(item)not in index:
                index.append(hand.index(item))
        if len(index) == len(combo):
            return True 
    return False

您检查 combo 中的每个项目并找到它在 hand 中出现的位置,以确保您不会再次在 hand 中找到相同的项目。如果 combo 中的所有项目都与 hand 中的索引相匹配,则您 return 为真(或者您需要 return 的任何内容)。如果您遍历所有组合,其中 none 与您匹配 return False.

您可以在列表理解中使用 any() 来做到这一点:

hand = ["apple", "apple", "banana", "cabbage", "durian"]
combos = [
    ["apple", "banana"],
    ["banana", "lettuce"],
    ["banana", "pear"],
    ["cabbage", "cabbage"]
]

match = any( a in hand and hand.count(b)>(a==b) for a,b in combos )

print(match) # True

要知道哪一个匹配:

matches = [ (a,b) for a,b in combos if a in hand and hand.count(b)>(a==b)]

print(*matches)
# ('apple', 'banana')

您也可以使用计数器 class:

from collections import Counter
comboCounts = list(map(Counter,combos))

handCounts  = Counter(hand)
match       = any(not combo-handCounts for combo in comboCounts)

print(match) # True