You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从扑克牌手牌中移除重复牌面数字?代码报错TypeError: 'int' object is not subscriptable求助

解决扑克牌手牌去重问题

先分析你的代码错误

你遇到的TypeError: 'int' object is not subscriptable错误,核心原因是把循环索引当成了列表元素

  • 你写的for i in range(len(l))里,i是整数类型的索引(比如0、1、2...),不是手牌里的具体牌(比如'6♠'),所以i[-2]试图对整数取下标,自然会报错。
  • 另外for j in (i+1, len(l))也不对,这是在循环两个整数(i+1和len(l)),不是遍历从i+1到列表末尾的所有元素,应该写成range(i+1, len(l))

正确的去重思路

我们需要提取每张牌的牌面数字/字母(比如'6♠'的牌面是'6','10♣'的牌面是'10','K♢'的牌面是'K'),然后保证每个牌面只保留一张牌(不管花色)。

下面给你几种实用的实现方案:

方案一:遍历+集合记录已出现的牌面(最直观)

这个方法逻辑清晰,适合新手理解:

hand = ['6♠', '6♣', '7♢', '10♣', '8♣', '2♣', '9♠', '8♢', '7♠', 'K♢', '9♡', 'Q♡', '10♢', '2♠', 'K♡', '2♢', '3♢', 'Q♢', '6♡', '4♣', 'A♡', '4♡', 'A♠', 'A♣', 'J♣', 'Q♠']
no_pairs = []
seen_ranks = set()  # 用集合存已经处理过的牌面,查询效率高

for card in hand:
    # 提取牌面:处理'10'这种两位的情况
    if card.startswith('10'):
        rank = '10'
    else:
        rank = card[0]
    if rank not in seen_ranks:
        seen_ranks.add(rank)
        no_pairs.append(card)

print(no_pairs)

运行后会保留每个牌面第一次出现的那张牌,结果顺序和原手牌一致。

方案二:用有序字典去重(简洁高效)

Python 3.7及以上的字典是有序的,利用字典键的唯一性,可以快速实现去重:

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

# 生成键为牌面,值为牌的字典,自动去重
rank_dict = {}
for card in hand:
    rank = '10' if card.startswith('10') else card[0]
    if rank not in rank_dict:
        rank_dict[rank] = card

# 提取字典的值就是去重后的手牌
no_pairs = list(rank_dict.values())
print(no_pairs)

这个方法和方案一效果一致,但代码更简洁,执行效率也更高。

方案三:修正你原来的双重循环思路

如果你想坚持用双重循环的方式,需要把索引和元素区分开,代码如下:

hand = ['6♠', '6♣', '7♢', '10♣', '8♣', '2♣', '9♠', '8♢', '7♠', 'K♢', '9♡', 'Q♡', '10♢', '2♠', 'K♡', '2♢', '3♢', 'Q♢', '6♡', '4♣', 'A♡', '4♡', 'A♠', 'A♣', 'J♣', 'Q♠']
hand.sort()  # 先排序让相同牌面的牌靠在一起
no_pairs = []

for i in range(len(hand)):
    # 提取当前牌的牌面
    current_card = hand[i]
    current_rank = '10' if current_card.startswith('10') else current_card[0]
    # 标记是否重复
    is_duplicate = False
    # 遍历之前的牌,检查是否有相同牌面
    for j in range(i):
        prev_card = hand[j]
        prev_rank = '10' if prev_card.startswith('10') else prev_card[0]
        if current_rank == prev_rank:
            is_duplicate = True
            break
    if not is_duplicate:
        no_pairs.append(current_card)

print(no_pairs)

这个方法通过排序后检查前面的元素是否重复,也能实现去重,但效率比前两种低一些(双重循环时间复杂度更高),适合用来理解循环逻辑。


内容的提问来源于stack exchange,提问作者heyhoezay

火山引擎 最新活动