繁体   English   中英

从类定义列表中删除namedtuple对象

[英]Delete a namedtuple object from a class defined list

下面是Luciano Romalho的“ Fluent Python”一类纸牌。 我希望可以复制代码,但我确实没有比这更好的简洁的类示例。

import collections
from random import choice

Card = collections.namedtuple('Card', ['rank', 'suit'])


class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits 
                       for rank in self.ranks]

    def __len__(self):
    return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

因此,此类的实例将有52张卡,每张卡都由“卡”对象中定义的一个命名元组组成。

我想画一张n张牌的手,以便它能反映在牌组中。

我尝试了以下方法:

def a_hand(deck, size):
    the_hand = []
    for n in range(size):
        c = choice(deck)
        the_hand.append(c)
        deck = [i for i in deck if i != c]
    return the_hand 

所以当我尝试:

>> deck = FrenchDeck()
>> a = a_hand(deck, 5)

我得到了帮助,但甲板未受影响:

>> hand
[Card(rank='9', suit='spades'),
 Card(rank='A', suit='hearts'),
 Card(rank='2', suit='diamonds'),
 Card(rank='8', suit='clubs'),
 Card(rank='10', suit='hearts')]

>> len(deck)
52

当我直接尝试插入器时:

>> c = choice(deck)
>> alt = [i for i in deck if i != c]

有用:

>> len(alt)
51

我知道这是由于FrenchDeck实例不受a_hand函数范围内发生的情况影响。

怎么做呢? 我试图在类中定义dunder-delitem函数,但没有正确使用它,也不确定是否要使用正确的函数,以及是否要在Card对象或FrenchDeck对象中定义它。

没错,这是由于在a_hand函数中FrenchDeck实例。 相反,您仅覆盖deck变量。 为了实现您的目标,您可以例如在FrenchDeck类中添加deal_hand方法,该方法将返回给定大小的一手牌,并从牌组本身中删除选定的牌。

您创建一个新的牌组,而不是更新现有的牌组。

deck = [i for i in deck if i != c]

这将创建一个列表,该列表由列表理解构建,并使其指向deck ,而不是指向已传递的原始列表。

如果要更改现有列表,则需要使用deck.remove(...)

(另外:尝试制作套组和指针组,而不是列表。它与域更匹配。)

真的,你只需要移动a_hand要的方法FrenchDeck

class FrenchDeck:
    # All previous code here, plus:

    def a_hand(self, size):
        the_hand = []
        for n in range(size):
            c = choice(self._cards)
            the_hand.append(c)
            self._cards.remove(c)
        return the_hand 

从卡座中取出卡时,也请从卡座中将其取出。 __getitem__使用list.pop

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits 
                       for rank in self.ranks]

    def __len__(self):
        print(f'__len__ called: {len(self._cards)}') 
        return len(self._cards)

    def __getitem__(self, position):
        print(f'getting item {position}')
        return self._cards.pop(position)

def a_hand(deck, size):
    the_hand = []
    for n in range(size):
        print('getting another card')
        c = choice(deck)
        the_hand.append(c)
    return the_hand

deck = FrenchDeck()
a = a_hand(deck, 5)

暂无
暂无

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

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