遍历(和更改)集合中所有变量的方法

时间:2019-05-26 07:59:26

标签: python loops iterator iteration

有哪些Python工具可以快速迭代和更改满足type == int(可能有一些例外)等条件的所有变量?
这种使用的一个例子是基于时间的编程,其中在模拟中的每个对象都添加了一个或多个相同的变量,例如每个粒子在其垂直位置掉落并改变-n(距离)。
我相信这类似于SQL中的WHERE
(这只是寻找建议的一般问题)

所需功能的伪代码:

function(variables_in_list) where (conditions)

更新此类下落粒子位置的简单方法如下代码所示:

class particle():
    def __init__(self):
        height = 100

particles = [particle() for _ in range(100)]

while True:
    for item in particles:
        if item.height > 0:
            item.height -= 1

在此示例中是particles中每个实例的迭代,更新了它们的height值。我正在寻找的是在这些实例中无需指定变量即可更新每个变量(例如int的某种类型)的方法。一种理想的方法是仅选择“类型”,例如int,然后将每个int更改一定的值。

3 个答案:

答案 0 :(得分:0)

您可以在循环中检查项目是否为int,例如

isinstance(item, int)

答案 1 :(得分:0)

您可以使用实例的__dict__访问所有实例变量。 如果您需要应用int或其他条件,可以使用instainceof或类似方法。

class particle(object):
    def __init__(self):
        self.height = 100

particles = [particle() for _ in range(2)]

for item in particles:
    item.height -= 1

for item in particles:
    for key in item.__dict__.keys():
        item.__dict__[key] = 5

item .__ dict __ [key] = 5 =>在这里,我访问实例变量并更改值。如果需要添加条件,可以在此处添加。

答案 2 :(得分:0)

前面的代码很乱(下面是更好的解决方案)

您可以在遥远的地方实现__iter__,它将返回实例的所有属性,然后您将能够实现所需的目标:

class particle:
    def __init__(self):
        self.x = 90
        self.y = 70

    def __iter__(self):
        yield from self.__dict__


particles = [particle() for _ in range(2)]

for particle in particles:
    for attribute in particle:
        current_val = getattr(particle, attribute)
        if isinstance(current_val, int):
            setattr(particle, attribute, current_val - 1)

for particle in particles:
    print(particle.x, particle.y)

输出

89 69
89 69

更好的解决方案

但是,我认为这不是正确的方法。更好的方法可能是在类本身内部实现属性修改。

class particle:
    def __init__(self):
        self.x = 90
        self.y = 70

    def change_all_attributes(self, attr_type, change_by):
        for attr_name, attr_value in self.__dict__.items():
            if isinstance(attr_value, attr_type):
                setattr(self, attr_name, attr_value + change_by)


particles = [particle() for _ in range(2)]

for particle in particles:
    particle.change_all_attributes(int, -1)
    print(particle.x, particle.y)

输出

89 69
89 69

您会得到什么:

  • 更多惯用代码。属性的更改是由类完成的,而不是由代码中某个地方的任意嵌套循环(易于调试)完成的。
  • 一种内置的方式来控制修改后的属性的类型以及更改的数量

可以通过使用属性的getter和setter来更进一步。