如何从python集中删除自定义对象的实例? [英] How to remove instance of custom object from python set?

查看:91
本文介绍了如何从python集中删除自定义对象的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 python 玩一些基本的卡片/套牌操作.您可以在下面看到我的 Card 类和 Deck 类.假设我知道有些牌已经死了,想将它们从牌组中移除.

I'm playing around with some basic card/deck manipulations in python. Below you can see my Card class and Deck class. Assume that I know that some cards are dead and would like to remove them from the deck.

import itertools

SUIT_LIST = ("h", "s", "d", "c")
NUMERAL_LIST = ("2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A")

class Card:
    def __init__(self, numeral, suit):
        self.numeral = numeral
        self.suit = suit
        self.card = self.numeral, self.suit
    def __repr__(self):
        return self.numeral + self.suit

class Deck(set):
    def __init__(self):
        for numeral, suit in itertools.product(NUMERAL_LIST, SUIT_LIST):
            self.add(Card(numeral, suit))

deck = Deck()    
dead_card = Card('J','s')
deck.remove(dead_card)

引发以下错误:

Traceback (most recent call last):

  File "<ipython-input-93-06af62ea1273>", line 23, in <module>
    deck.remove(dead_card)

KeyError: Js

从我的套牌中移除死牌的正确方法是什么?为什么我这样做的方式不起作用?

What is the proper way of removing dead cards from my deck? And why the way I do it does not work?

推荐答案

您需要在 Card 类中使用两个新方法,以使集合和字典中的成员资格正常工作:

You'll need two new methods on your Card class, for membership in sets and dicts to work sanely:

class Card:
    ...
    def __hash__(self):
        return hash(self.card)
    def __eq__(self, other):
        if isinstance(other, Card):
            return self.card == other.card
        return NotImplemented

这是因为集合是通过哈希表实现的,除非您定义如何哈希并比较您的自定义类的实例,一个基于 身份 的哈希(CPython 中的内存位置)将用作默认值.使用 id 在这里提供了一个相当糟糕的默认值 - 两张具有相同号码/花色的牌不会被视为相等",并且不会识别 Deck 中的成员资格.

This is because sets are implemented with hash tables, and unless you define how to hash and compare instances of your custom class, a hash based on the identity (memory location in CPython) will be used as a default. Using id provides a fairly crappy default here - two cards with same number/suit would not be considered "equal" and the membership in a Deck is not recognised.

这篇关于如何从python集中删除自定义对象的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆