Подсчёт ЧАСТИЧНО совпадающих элементов в списке

Дано: список "карт на руках" (моделируем игру). Элементы списка представлены в виде строк типа: '6♡' или '10♣'.

ВОПРОС: Как грамотно выявить карты с повторяющимся номиналом, то есть рассматривая только строки с отброшенным последним символом, обозначающим масть? Чтобы результат выводился в виде объекта, где элементы расположены в порядке убывания повторений. Уже имеется функция getnominal(card), которая выводит числовое значение номинала. На ум приходит только составление отдельного списка, где будут только номиналы, но кажется, это слишком неграмотный подход.


Ответы (1 шт):

Автор решения: gil9red

Есть список:

items = ['4♣', '4♡', '6♡', '10♣', '9♣']

Подсчет по масти и по номиналу:

number = sum(1 for x in items if '♣' in x)
print(number)
# 3

number = sum(1 for x in items if '4' in x[:-1])
print(number)
# 2

Сортировка по масти и с номиналом по убыванию:

new_items = sorted(items, key=lambda x: (x[-1], int(x[:-1])), reverse=True)
print(new_items)
# ['10♣', '9♣', '4♣', '6♡', '4♡']

Группирование по масти, где масть будет ключом, а значением список карт с этой мастью:

from collections import defaultdict

suit_by_card = defaultdict(list)
for x in items:
    suit = x[-1]
    suit_by_card[suit].append(x)
print(suit_by_card)
# {'♣': ['4♣', '10♣', '9♣'], '♡': ['4♡', '6♡']}

Аналогично выше, только ключом будет номинал:

value_by_card = defaultdict(list)
for x in items:
    value = int(x[:-1])
    value_by_card[value].append(x)
print(value_by_card)
# {'4': ['4♣', '4♡'], '6': ['6♡'], '10': ['10♣'], '9': ['9♣']}

Пример использования Counter для составления списка дубликатов:

from collections import Counter

items = ['4♣', '4♡', '9♣', '4♡', '6♡', '4♡', '10♣', '9♣']

card_by_number = Counter(items)
print(card_by_number)
# {'4♡': 3, '9♣': 2, '4♣': 1, '6♡': 1, '10♣': 1}

duplicates = [k for k, v in card_by_number.items() if v > 1]
print(duplicates)
# ['4♡', '9♣']

UPD.

from collections import defaultdict

items = ['6♠', '9♠', '9♡', '10♢', '13♠', '13♡', '13♢', '14♣']

value_by_card = defaultdict(list)
for x in items:
    value = int(x[:-1])
    value_by_card[value].append(x)
print(value_by_card)
# {6: ['6♠'], 9: ['9♠', '9♡'], 10: ['10♢'], 13: ['13♠', '13♡', '13♢'], 14: ['14♣']}

order_nums = []
nums = sorted(value_by_card.keys(), reverse=True)
for num in nums:
    cards = value_by_card[num]
    print(cards)
    order_nums.append(cards)
# ['14♣']
# ['13♠', '13♡', '13♢']
# ['10♢']
# ['9♠', '9♡']
# ['6♠']

print(order_nums)
# [['14♣'], ['13♠', '13♡', '13♢'], ['10♢'], ['9♠', '9♡'], ['6♠']]

PS.

  • x[-1] -- это возвращает последний символ 10♣ ->
  • x[:-1] -- это возвращает всё, кроме последнего символа 10♣ -> 10
→ Ссылка