[英]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.