Python:在创建新对象之前检查对象是否已存在

时间:2014-08-21 14:28:00

标签: python for-loop python-3.x

请帮我看看下面我缺少的东西。我首先创建了我的类的三个对象,并将它们添加到集合列表中。在创建任何其他对象之前,我想检查以确保该人员不在列表中。如果此人已存在,则不应再次创建此人。我希望通过if prompt_fname == person.fname and prompt_lname == person.lname:来实现检查。显然,我没有正确地执行它,因为该程序仍然运行并创建了已存在于列表中的同一个人。它创造了这个人两次。如何修改以捕获此内容,以便不再创建列表中已存在的人员。此外,不应在循环的每次迭代中反复创建任何新人。我是编程新手,所以请不要在答案中留下太多细节。非常感谢。

class Person(object):

    personslist = []
    '''Creates a person object'''
    def __init__(self, firstname, lastname):
        self.lname = lastname.title()
        self.fname = firstname.title()
        Person.personslist.append(self)

    def __str__(self):
        return "{0} {1}".format(self.fname, self.lname)

    def __repr__(self):
        return "{0} {1}".format(self.fname, self.lname)


Person("Adamu", "Emeka")
Person("Femi", "Ojukwu")
Person("Wole", "Jonathan")


prompt_fname = "Adamu"
prompt_lname = "Emeka"

print(Person.personslist)

for person in Person.personslist:
    if prompt_fname == person.fname and prompt_lname == person.lname:
        pass
    else:
        Person(prompt_fname, prompt_lname)

print(Person.personslist)

产量

[Adamu Emeka, Femi Ojukwu, Wole Jonathan]
[Adamu Emeka, Femi Ojukwu, Wole Jonathan, Adamu Emeka, Adamu Emeka]

使用Python 3.4.1

5 个答案:

答案 0 :(得分:3)

您的循环正在检查每个条目,如果该特定条目不相等,则会创建另一个实例。但是,如果该特定条目 相等,它不会停止,它只会继续到下一个项目,这将不相等。这就是为什么你实际上在最后得到两个额外条目的原因。

您可以通过保留标志来解决此问题:

found = False
for person in Person.personslist:
    if prompt_fname == person.fname and prompt_lname == person.lname:
        found = True
        break
if not found:
    Person(prompt_fname, prompt_lname)

然而,有一种更好的方法可以做到这一点:你的方式非常低效,因为它每次都需要线性扫描。相反,请保留一个由其全名键入的对象字典:

class Person(object):

    persons_dict = {}
    '''Creates a person object'''
    def __init__(self, firstname, lastname):
        self.lname = lastname.title()
        self.fname = firstname.title()
        fullname = "%s %s" % (self.fname, self.lname)
        Person.persons_dict[fullname] = self

现在你可以一次性检查:

if "%s %s" % (prompt_fname, prompt_lname) not in Person.persons_dict:

答案 1 :(得分:1)

此代码不会做它应该做的事情:

for person in Person.personslist:
    if prompt_fname == person.fname and prompt_lname == person.lname:
        pass
    else:
        Person(prompt_fname, prompt_lname)

使用for person in Person.personslist:,它会覆盖您已经创建的三个Person()对象。第一个是' Adamu Emeka'所以名字是平等的,而且如果'声明到达'通过'。但是,人员列表中的下一个项目名称为' Femi Ojukwu',if中的名称不相等,因此它到达else子句并创建一个新对象。第三个名称也是如此。这就是为什么你有两个额外的Adamu Emeka副本。

请参阅Daniel Roseman的替代解决方案的答案

答案 2 :(得分:1)

每次添加名称前都要检查完整列表:

name = prompt_fname + prompt_lname

if not any(person.fname + person.lname == name for person in Person.personslist):
    Person(prompt_fname, prompt_lname)

答案 3 :(得分:0)

尝试:

if prompt_fname.title() == person.fname and prompt_lname.title() == person.lname:

因为你在Person的 init 中使用了title()方法

答案 4 :(得分:-1)

在您的代码中,一旦找到不是Adamu Emeka的人,就会在列表中添加另一个Adamu Emeka。这就是为什么两个Adamu Emeka被添加的原因。请尝试以下方法:

alreadyExists = False;
for person in Person.personslist:
    if prompt_fname == person.fname and prompt_lname == person.lname:
        alreadyExists = True;
        break;
if not alreadyExists:
    Person(prompt_fname, prompt_lname)

更好的方法是使用set,这样您就不必执行线性搜索。要使设置正常工作,您必须implement __hash__ and __eq__ methods