2012-05-11 212 views
2

这里对象添加到Python的集收集,并确定是我的代码:通过对象的属性

#!/usr/bin/python 

class Person(): 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 

    def get_detail(self): 
     print "I am %s , my age is %d" % (self.name, self.age) 


if __name__ == '__main__': 
    tom = Person('tom', 18) 
    jack = Person('jack', 20) 
    mary = Person('mary', 22) 
    mary2 = Person('mary2', 22) 
    mary3 = Person('mary3', 22) 

    person_set = set([]) 
    person_set.add(tom) 
    person_set.add(jack) 
    person_set.add(mary) 
    person_set.add(mary2) 
    person_set.add(mary3) 
    for man in person_set: 
     man.get_detail() 

结果:

I am jack , my age is 20 
I am mary2 , my age is 22 
I am tom , my age is 18 
I am mary , my age is 22 
I am mary3 , my age is 22 

预期结果:

I am jack , my age is 20 
I am tom , my age is 18 
I am mary , my age is 22 

按照预期结果,我的意思是当我将Person添加到person_set中时,我想确定新人是否已经完全通过属性age。什么是正确的方式来做到这一点?

+1

所以,作为一个例子,'弗兰克,年龄19'将是一样'希瑟,19'年代,如果你只是按年龄比较? – jamylak

+0

是的,只有第一个被添加到集合中才会被存储 – sashimi

+3

@sashimi,那么你需要一个字典,其中age作为key,Person对象作为值。 – spinlok

回答

15

当一个新对象被添加到python集合中时,首先计算该对象的哈希代码,然后,如果一个或多个具有相同哈希代码的对象已经在集合中,则测试这些对象与新对象平等。

这样做的结果是你需要在你的类上实现__hash__(...)__eq__(...)方法。例如:

>>> class Person(object): 
... def __init__(self, name, age): 
...  self.name = name 
...  self.age = age 
... def __eq__(self, other): 
...  return self.age == other.age 
... def __hash__(self): 
...  return hash(self.age) 
... def get_detail(self): 
...  print "I am %s, my age is %d" % (self.name, self.age) 
... 
>>> 
>>> tom = Person('tom', 18) 
>>> jack = Person('jack', 20) 
>>> mary = Person('mary', 22) 
>>> mary2 = Person('mary2', 22) 
>>> mary3 = Person('mary3', 22) 
>>> 
>>> person_set = set() 
>>> person_set.add(tom) 
>>> person_set.add(jack) 
>>> person_set.add(mary) 
>>> person_set.add(mary2) 
>>> person_set.add(mary3) 
>>> 
>>> len(person_set) 
3 
>>> 
>>> for p in person_set: 
... p.get_detail() 
... 
I am tom, my age is 18 
I am jack, my age is 20 
I am mary, my age is 22 

但是,你应该非常仔细地对正确实施__hash____eq__应该是什么类的想法。上面的例子是有效的,但是没有意义(例如,__hash____eq__仅仅是根据年龄定义的)。

+0

谢谢〜这就是我想要的,我知道这很奇怪。我将使用的** Person **这样的类非常简单,因此无论是否改写都不重要。我知道这是不受欢迎的^ _ ^,我会小心使用它 – sashimi

0

如果需要简单地添加新的用户设置,你可以使用这个简单的检查:

for man in person_set: 
    if man.age is tom.age: 
     print 'exist' 

,但如果你有很多元素的集合,需要实现__ 哈希 __( ...),__ EQ __(...)