如何遍历具有两个不同条件的列表?

时间:2019-06-18 15:48:57

标签: python list class for-loop minimum

伙计们,我遇到了一个for循环问题,我找不到在线解决方案。

让我们说我创建了两个类,一个用于人,一个用于动物。通过为动物类设置一个循环方法,以遍历“人民”年龄列表,我希望找到每个具有相同年龄或至少最小年龄差距的宠物的所有者(此示例只是为了使代码看起来更简单) )。我使用min()函数来查找年龄差距最小的人,并且工作正常。

但是,如果我在选择过程中又添加了一个条件怎么办?例如,我只想将动物分配给那些拥有少于3只宠物的人,这意味着即使一个人的年龄差距最小,但如果它已经拥有3只宠物,则不能将其分配给该人。在这种情况下,循环将不得不寻找年龄差距最小的下一个拥有少于3只宠物的人。在我的情况下,必须将A1分配给P1,因为年龄差距最小的人拥有少于3只宠物。

到目前为止,这是我的代码:

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

P1=People("John",16, 1)
P2=People("Alex",10, 4)
P3=People("Anna", 20, 3)


People_List=[P1, P2, P3]
People_Age=[P1.age, P2.age, P3.age]

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

    def find(self):
        closest_age = (min(People_Age, key=lambda x: abs(x - self.age)))
        for a in People_List:
            if a.age ==closest_age and a.pets_owned<3:
                self.owner=a.name
                a.pets_owned+=1
                break

            elif a.age==closest_age and a.pets_owned >=3:
                pass #this is where I`m stuck


        print(self.owner)


A1=Animal("Snoopy",7,"not_owned_yet")


A1.find()

2 个答案:

答案 0 :(得分:1)

如果您知道由于条件而不会包括某些人员,那么我将预先过滤传入列表以排除这些人员。基本上,根本不用使用for循环,只需过滤列表,找到最小值,然后添加宠物即可。

0.866

答案 1 :(得分:0)

通过使排序键返回一个元组,可以基于多个属性进行排序。在我的示例中,首先我们根据年龄差距(较高的优先级)进行排序,然后根据拥有的宠物数量(较低的优先级)进行排序。您不需要像我一样使用sorted,因为我仅使用它来演示如何基于多个属性进行排序。您可能要使用具有相同密钥的min来获得最合适的人。您还需要修改assign_new_owner,以实际分配新所有者,而不是(使用min)而不是打印人员:

class Person:

    def __init__(self, name, age, pets_owned):
        self.name = name
        self.age = age
        self.pets_owned = pets_owned

    def __str__(self):
        return f"{self.name}, age {self.age} owns {self.pets_owned} pet(s)."

class Animal:

    def __init__(self, name, age, owner=None):
        self.name = name
        self.age = age
        self.owner = owner

    def assign_new_owner(self, people):
        sorted_people = sorted(people, key=lambda p: (abs(p.age - self.age), p.pets_owned))
        for person in sorted_people:
            print(person)

def main():

    people = [
        Person("Alex", 16, 0),
        Person("Nigel", 15, 2),
        Person("Fred", 10, 3),
        Person("Tom", 10, 0),
        Person("Tyler", 15, 0),
        Person("Sam", 15, 1)
        ]

    animal = Animal("Snoopy", 10)
    animal.assign_new_owner(people)

    return 0

if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

 Tom, age 10 owns 0 pet(s).
 Fred, age 10 owns 3 pet(s).
 Tyler, age 15 owns 0 pet(s).
 Sam, age 15 owns 1 pet(s).
 Nigel, age 15 owns 2 pet(s).
 Alex, age 16 owns 0 pet(s).

编辑:使用min后,代码可能看起来像这样:

class Person:

    def __init__(self, name, age, pets_owned):
        self.name = name
        self.age = age
        self.pets_owned = pets_owned

    def __str__(self):
        return f"{self.name}, age {self.age} owns {self.pets_owned} pet(s)."

class Animal:

    def __init__(self, name, age, owner=None):
        self.name = name
        self.age = age
        self.owner = owner

    def __str__(self):
        return f"{self.name}, age {self.age} is owned by {self.owner.name if self.owner else 'no one'}."

    def assign_new_owner(self, people):
        self.owner = min(people, key=lambda p: (abs(p.age - self.age), p.pets_owned))

def main():

    people = [
        Person("Alex", 16, 0),
        Person("Nigel", 15, 2),
        Person("Fred", 10, 3),
        Person("Tom", 10, 0),
        Person("Tyler", 15, 0),
        Person("Sam", 15, 1)
        ]

    animal = Animal("Snoopy", 10)
    print(animal)
    animal.assign_new_owner(people)
    print(animal)

    return 0

if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

Snoopy, age 10 is owned by no one.
Snoopy, age 10 is owned by Tom.