如何使用python查找成对的卡片包列表

Posted

技术标签:

【中文标题】如何使用python查找成对的卡片包列表【英文标题】:How to find pairs of a card pack list using python 【发布时间】:2020-08-10 02:22:41 【问题描述】:

我在 python 中有以下列表。

list = ['10♠', '10♣', '2♡', '4♠', '4♣', '5♡', '5♣', '6♡', '6♣', '7♠', '7♡', '7♢', '7♣', '8♡', '8♢', '8♣', '9♡', '9♢', '9♣', 'A♠', 'A♢', 'A♣', 'J♢', 'K♠', 'K♢', 'Q♡']

如何从中删除对?例如,如果一个数字出现奇数次,则应保留它的最后一次出现。所有其他人都应该被删除。包括所有出现偶数次的。

例如:来自'9♡''9♢''9♣',只应保留'9♣'

有人可以帮我解决这个问题吗?

我尝试使用以下代码首先识别索引。但仍然没有运气。

i = 0
        while i < len(deck): 
            count = 0
            k = len(deck[i])
            pivot = i
            j = i
            while j < len(deck): 
                if deck[i][:k-1] == deck[j][:k-1]:
                    print(deck[i]+','+deck[j])
                    count+= 1 
                    pivot = j
                j+=1
            if (count %2 != 0): 
                print('pivot:'+str(pivot))
            i = pivot +1
            i +=1

无需考虑符号。只想从列表中删除对。

请提供您的建议。

【问题讨论】:

订单重要吗? @MarkMeyer 我正要问同样的问题...... 【参考方案1】:

这是你要找的吗?

from collections import defaultdict
deck = ['10♠', '10♣', '2♡', '4♠', '4♣', '5♡', '5♣', '6♡', '6♣', '7♠', '7♡', '7♢', '7♣', '8♡', '8♢', '8♣', '9♡', '9♢', '9♣', 'A♠', 'A♢', 'A♣', 'J♢', 'K♠', 'K♢', 'Q♡']

# Create a dictionary and group all the cards with same number
groups = defaultdict(list)
for card in deck:
    key = card[:-1]
    groups[key].append(card)

new_deck = []
for subgroup in groups.values():
    # iterate through the dictionary
    # If you have odd number of cards in a subgroup
    # consider the last card in that subgroup
    if len(subgroup)%2 == 1:
        new_deck.append(subgroup[-1])

for card in new_deck:
    print(card)

输出

2♡ 8♣ 9♣ A♣ J♢ Q♡

编辑:感谢 RoadRunner,对 groups.values 的第二次迭代进行了小幅简化。

【讨论】:

@RoadRunner 关于.values,你是对的!我刚刚看到我们基本上有相同的想法 :) 这感觉是解决这个问题的一种自然方式。【参考方案2】:

将卡片对分组为collections.defaultdict,然后使用列表推导仅返回新列表中不均匀对中的最后一张卡片:

from collections import defaultdict

lst = ['10♠', '10♣', '2♡', '4♠', '4♣', '5♡', '5♣', '6♡', '6♣', '7♠', '7♡', '7♢', '7♣', '8♡', '8♢', '8♣', '9♡', '9♢', '9♣', 'A♠', 'A♢', 'A♣', 'J♢', 'K♠', 'K♢', 'Q♡']

cards = defaultdict(list)
for card in lst:
    cards[card[:-1]].append(card)

result = [pairs[-1] for pairs in cards.values() if len(pairs) % 2]

print(result)

输出:

['2♡', '8♣', '9♣', 'A♣', 'J♢', 'Q♡']

【讨论】:

【参考方案3】:

保持相同的顺序,可以使用:

import re

l = ['10♠', '10♣', '2♡', '4♠', '4♣', '5♡', '5♣', '6♡', '6♣', '7♠', '7♡', '7♢', '7♣', '8♡', '8♢', '8♣', '9♡', '9♢', '9♣', 'A♠', 'A♢', 'A♣', 'J♢', 'K♠', 'K♢', 'Q♡']

nc, nl = [], [0]

for x in l:
    clean = re.sub(r"[^A-Z\d]", "", x)
    if clean != nl[-1]:
        nl.append(clean)
        nc.append(x)
    else:
        del nl[-1]
        del nc[-1]

print(nc)
# ['2♡', '8♣', '9♣', 'A♣', 'J♢', 'Q♡']

Demo

【讨论】:

【参考方案4】:

首先list是一个保留关键字,你不应该用保留关键字命名你的变量,使用lst而不是list

现在,这是最小的解决方案:

lst = ['10♠', '10♣', '2♡', '4♠', '4♣', '5♡', '5♣', '6♡', '6♣', '7♠', '7♡', '7♢', '7♣', '8♡', '8♢', '8♣', '9♡', '9♢', '9♣', 'A♠', 'A♢', 'A♣', 'J♢', 'K♠', 'K♢', 'Q♡']
dictionary = dict.fromkeys(list('A23456789JQK')+['10'])   

for item in lst: 
    dictionary[item[:-1]] = item if dictionary[item[:-1]] is None else None                                                                                    

print(list(filter(None.__ne__, dictionary.values())))

输出:

['A♣', '2♡', '8♣', '9♣', 'J♢', 'Q♡']

【讨论】:

以上是关于如何使用python查找成对的卡片包列表的主要内容,如果未能解决你的问题,请参考以下文章

C# Regex - 如何从字符串中删除多个成对的括号

成对的数字或指数

位运算-查找数组中唯一成对的数

最快的 c++ / stl 算法来查找成对的字符串

如何制作一个可以列出对的列表?

如何在 mySQL 中从聚合中排除成对的行?