如何从扑克牌手牌中移除重复牌面数字?代码报错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




