简体   繁体   English

检查列表是否包含4个相同值的元素

[英]check if a list contains 4 elements of the same value

So I'm stuck on a newbie problem once more :D 所以我再次陷入了新手问题:D

I'm trying to mash together a text based game of go-fish against the computer. 我正在尝试将基于文本的钓鱼游戏与计算机融合在一起。

Ok so 1 card is actually a tuple of elements from two lists. 好吧,一张卡片实际上是两个列表中元素的元组。

suits = ['Clubs', 'Diamonds', 'Spade', 'Hearts']
ranks = [None, 'ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king']

Then that is added to a deck and shuffled and whatnot and then dealt into hands. 然后将其添加到牌组中并进行混洗,然后处理。 (got most of it from the book thinkpython i think. Learned a lot about class structure and inheritance in the process.) (从我认为的thinkpython书中获得了大部分信息。在该过程中学习了很多有关类结构和继承的知识。)

So one hand might look like this 所以一只手可能看起来像这样

['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']

As you can see that hand contains four of the same rank so that's 1 point for the player. 如您所见,这只手包含四只相同等级的牌,因此对玩家来说是1分。 But how would I check if the hand contains four instances of any item in the ranks list? 但是我该如何检查该手牌是否包含等级列表中任何项目的四个实例? Do I have to iterate through each item in the list or there some clean and simple way to it? 我是否必须遍历列表中的每个项目,或者有一些简洁明了的方法?


EDIT 编辑
Thanks a lot for all the answers guys. 非常感谢你们的所有答案。 :D But I'm getting an attribute error when I try to use 'split' on the items in the hand. :D但是,当我尝试对手中的物品使用'split'时,出现属性错误。 Guess I should have posted more of the code I'm running. 猜猜我应该发布更多正在运行的代码。

Full code and traceback here 完整的代码和追溯在这里
http://pastebin.com/TwHkrbED http://pastebin.com/TwHkrbED

Is there something wrong with how the methods are defined in Card? Card中的方法定义方式有问题吗? I've been hacking around for hours trying to make it work, but no luck. 我花了好几个小时试图使它工作,但没有运气。

EDIT2 编辑2
Made some changes to the deck generating part. 对卡座生成部分进行了一些更改。 Now the whole deck is a list of tuples and a lot less code. 现在整个甲板上是一个元组列表和更少的代码。

thedeck=[]
class Deckofcards:
    suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
    ranks = ['Ace', '2', '3', '4', '5', 
        '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']
    def __init__(self):
        for i in self.suits:
            for a in self.ranks:
                thedeck.append((i, a))

Seems like the other way was overly complicated, but idk. 似乎另一种方式过于复杂,但idk。 I'll see how it goes tomorrow, adding the actual game parts. 我将在明天看到进展,并添加实际的游戏部件。

I might suggest a slight refactoring: Represent each card in a hand as a tuple of (rank, suit) . 我可能会建议稍微重构一下:将手中的每张卡表示为(rank, suit)的元组。 So your example hand would be: 因此,您的示例示例为:

hand = [('2', 'Clubs'),
        ('king', 'Diamonds'),
        ('2', 'Diamonds'),
        ('2', 'Spades'),
        ('2', 'Hearts')]

Then I'd suggest a couple of auxiliary functions to help you determine the value of a hand: 然后,我建议使用一些辅助功能来帮助您确定一手牌的价值:

from collections import defaultdict

def get_counts(hand):
    """Returns a dict mapping card ranks to counts in the given hand."""
    counts = defaultdict(int)
    for rank, suit in hand:
        counts[rank] += 1
    return counts

def get_points(hand):
    """Returns the number of points (ie, ranks with all 4 cards) in the given
    hand."""
    return sum(1 for count in get_counts(hand).itervalues() if count == 4)

Edit: Switched to using sum in the get_points function, which seems clearer to me. 编辑:get_points函数中切换为使用sum ,对我来说似乎更清楚。

Working with these functions and the example hand you gave, you get output like so: 使用这些功能和您提供的示例手,您将获得如下输出:

>>> get_counts(hand)
defaultdict(<type 'int'>, {'king': 1, '2': 4})

>>> get_points(hand)
1

Here's one way: 这是一种方法:

x = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']
ranks = [i.split()[1] for i in x]
fourofakind = any(ranks.count(i)==4 for i in set(ranks))

fourofakind is then True if there are four cards of the same rank in the hand. 如果fourofakind有四张相同等级的牌, fourofakind为True。

If you are looking for an extended kind of functionality: 如果您正在寻找扩展功能:

hand = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']
hand_ranks = [i.split()[1] for i in x]
fourofakind = {}
for i in set(hand_ranks):
    fourofakind[i] = (hand_ranks.count(i) == 4)

Would give you a dict() mapping card rank (of cards in the hand) to whether you have 4 of that rank. 将为您提供dict()映射纸牌等级(手中的纸牌),以确定您是否有该等级4。

A bit more general than Justin's: 比贾斯汀的通用一点:

suits = ['Clubs', 'Diamonds', 'Spade', 'Hearts']
ranks = [None, 'ace', '2', '3', '4', '5', '6', '7', \
'8', '9', '10', 'jack', 'queen', 'king']

hand = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts king']
rankshand = [i.split()[1] for i in hand]

fourofakind = [hr for hr in ranks if rankshand.count(hr)==4]
threeofakind = [hr for hr in ranks if rankshand.count(hr)==3]
pair = [hr for hr in ranks if rankshand.count(hr)==2]

fourofakind
[]
threeofakind
['2']
pair
['king']

With the ability to see which rank has the set. 具有查看已设置等级的能力。

The new built-in Counter class added in Python 2.7 to the standard library collections module makes this fairly easy. 在Python 2.7中添加到标准库collections模块的新的内置Counter类使此操作相当容易。

suits = ['Clubs', 'Diamonds', 'Spade', 'Hearts']
ranks = [None, 'ace', '2', '3', '4', '5', '6', '7',
         '8', '9', '10', 'jack', 'queen', 'king']
hand = ['Clubs 2', 'Diamonds king', 'Diamonds 2', 'Spades 2', 'Hearts 2']

from collections import Counter

counts = Counter(card.split()[1] for card in hand)
four_of_a_kind = [rank for rank,count in counts.iteritems() if count == 4]
print 'four_of_a_kind:', four_of_a_kind
# four_of_a_kind: ['2']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM