【问题标题】:Python Count Method: Can It Accept Object Attribute References?Python 计数方法:它可以接受对象属性引用吗?
【发布时间】:2013-09-22 14:57:05
【问题描述】:

不久前,我用 Javascript 构建了一个简单的扑克游戏,并想用 Python 从头开始​​。这是到目前为止的代码(您可以跳到最后):

#imports
import random
#basics
values = range(2,15)
suits = ['Clubs','Spades','Diamonds','Hearts']
#card object
class Card:
    def __init__(self,suit,value,name):
        self.suit = suit
        self.value = value
        self.name = name
        if self.value < 11:
            self.name = str(self.value) + ' of'
        if self.value == 11:
            self.name = 'Jack of'
        if self.value == 12:
            self.name = 'Queen of'
        if self.value == 13:
            self.name = 'King of'
        if self.value == 14:
            self.name = 'Ace of'
#deck
deck = []
#load and shuffle deck
for s in suits:
    for v in values:
        deck.append(Card(s,v,'o'))
random.shuffle(deck)
#load hands
your_hand = random.sample(deck,7)
for card in your_hand:
    deck.remove(card)
#determine hands
def find_matches(hand):
    class Match:
        def __init__(self,value,amount):
            self.value = value
            self.amount = amount
    matches = [Match(card.value,hand.count(card.value)) for card in hand]
    for x in matches:
        print x.value,x.amount
find_matches(your_hand)

是的,我意识到这并不完美(我们总是很感激建议!)。我的问题是制作可靠的匹配查找功能。我尝试了几种不同的方法,但是对于这个hand.count(card.value),每个元素都显示为 0。计数方法将接受哪些参数的问题?还是与我的代码的某个方面有关?

感谢您的帮助!

【问题讨论】:

    标签: python oop object count


    【解决方案1】:

    hand.count(card.value) 的问题在于它计算手中有多少Card 对象等于其中一个的整数值,因为您比较两个不同的对象,所以它始终为零。一个简单的解决方法是将所有整数卡值提取到一个单独的列表中,并改用count()方法:

    def find_matches(hand):
        class Match:
            def __init__(self, value, amount):
                self.value = value
                self.amount = amount
        values = [card.value for card in hand]  # list of extracted card values
        matches = [Match(card.value, values.count(card.value)) for card in hand]
        for x in matches:
            print x.value, x.amount
    

    通过此更改,它将执行以下操作:

    10 1
    4 1
    9 1
    3 1
    12 2
    12 2
    6 1
    

    做类似事情的更 Pythonic 的方法是使用带有生成器表达式的collections.Counterclass:

    from collections import Counter
    
    counter = Counter(card.value for card in your_hand)
    print '{} unique values: {}'.format(len(counter), counter)
    

    同一手牌会给你:

    6 unique values: Counter({12: 2, 3: 1, 4: 1, 6: 1, 9: 1, 10: 1})
    

    我认为这在评估手部时会更容易使用(它是字典子类)。

    【讨论】:

    • 我之前使用了非常相似的东西,但我想要一种更 Pythonic 的方式来表达它。不过,很高兴知道为什么我目前的方法不起作用 - 谢谢!
    【解决方案2】:

    hand.count(card.value) 将检查card.value 在牌组中出现的次数。那是 0,因为该值是一个数字,并且卡片组中没有数字,只有 Cards。

    您可以通过sum(card.value == 5 for card in hand) 获取hand 中的卡片数量,其中card.value == 5。这是因为a == b 有一个布尔值TrueFalse,它们在数值上分别等于10

    所以它遍历手 (for card in hand),进行比较 (card.value == 5) 并总结 Trues 的数量,尽管它是内联的,所以列表存储在内存中。

    【讨论】:

      【解决方案3】:

      您的问题得到了很好的回答,所以这里有一些其他的 cmets:

      首先,Card.__init__() 中的蛇形链 ifs 最好用字典查找代替。喜欢做:

      value2name = dict((val, str(val)) for val in values)
      for val, name in (11, 'Jack'), (12, "Queen"), (13, "King"), (14, "Ace"):
          value2name[val] = name
      

      在您设置values 之后,然后将所有__init__() 替换为:

              self.name = value2name[value] + " of " + suit
      

      那么some_card.name将显示为(例如):

      King of Spades
      5 of Spades
      Ace of Hearts
      [etc]
      

      其次,如果你使用random.shuffle(),那么使用random.sample() 是没有意义的——反之亦然。只用一个。由于您稍后可能想要剥离其他手,shuffle() 更好。洗牌后,可以非常有效地从牌堆中取出 7 张随机牌,如下所示:

      your_hand = deck[-7:]
      del deck[-7:]
      

      从列表的末尾删除一个切片在 CPython 中非常有效。实际上,实现只是记录了列表的大小现在减去了删除元素的数量——不需要重新排列。

      要获得另外 7 张卡片,只需执行相同操作即可。或者把它放在一个函数中:

      def deal(deck, n):
          if n <= 0:
              raise ValueError("n must be > 0")
          if n > len(deck):
              raise ValueError("asked for more cards than remain")
          result = deck[-n:]
          del deck[-n:]
          return result
      

      然后:

      your_hand = deal(deck, 7)
      

      稍后。

      玩得开心! :-)

      【讨论】:

        猜你喜欢
        • 2015-12-23
        • 1970-01-01
        • 2011-04-10
        • 1970-01-01
        • 2011-03-11
        • 2013-10-27
        • 2020-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多