首页 > 解决方案 > 在这种情况下,避免混淆循环的最佳方法是什么?

问题描述

所以我想编辑一个由类组成的列表,这段代码是模拟两只动物互相吃的。此功能是关于一种动物(捕食者)吃另一种动物(猎物)。为了避免当我从列表中删除一只动物时循环变得“混乱”,我决定这样做:最强的捕食者应该先吃,他应该吃最弱的猎物,检查他是否会吃的概率尝试或不尝试吃掉猎物。

def eat_predator(self):
    if len(self.specie_classes["Prey"]) > 0:
        self.specie_classes["Predator"].sort(
            key=lambda specie: specie.strength, reverse=True
        )
        for pred in self.specie_classes["Predator"]:
            prey_survivors= []
            food_apetite= pred.req['Apetite'] # This is how much food he wishes to eat
            current_food = 0
            self.specie_classes["Prey"].sort(
                key=lambda specie: specie.strength
            )
            for prey in self.specie_classes["Prey"]:
                if food_apetite >= current_food:
                    break

                if specie.determine_kill(prey):
                    current_food += prey.weight
                    pred.increase_eat_weight(prey.weight)
                    prey_survivors = [
                        surv_prey
                        for surv_prey in self.specie_classes["Prey"]
                        if surv_prey != prey
                    ]

            self.specie_classes["Prey"] = prey_survivors

这是我目前的解决方案,我的主要问题是如何避免每次我想更新包含 Prey(动物)类的列表时创建一个新列表(不破坏迭代)

这是我希望避免的:

d = list(range(10))
for n in d:
    print('Testing', n)
    if n % 2 == 0 or n % 3 == 0:
        d.remove(n)
print(d)

Testing 0
Testing 2
Testing 4
Testing 6
Testing 8
[1, 3, 5, 7, 9] 

标签: pythonoop

解决方案


一种方法是创建一个包含要删除的索引的列表/集,然后d通过排除这些索引来重新创建:

In [74]: d = list(range(10))                                                                                                                                                                                                                                                                                            

In [75]: deleteme = set()  # we'll track the indices to be deleted, here                                                                                                                                                                                                                                                                                             

In [76]: for i,n in enumerate(d): 
    ...:     if n%2==0 or n%3==0: 
    ...:         deleteme.add(i)  # delete this index
    ...:                                                                                                                                                                                                                                                                                                                

In [77]: d = [e for i,e in enumerate(d) if i not in deleteme]                                                                                                                                                                                                                                                           

In [78]: d                                                                                                                                                                                                                                                                                                              
Out[78]: [1, 5, 7]

推荐阅读