簡體   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