2

我有一个列表列表。每个子列表包含自定义类的对象。我想要做的是将每个类对象的某个属性设置为 0。执行此操作的简单方法是双循环或类似的:

for subl in L:
  for myObj in subL:
    myObj.attr = 0

或者,我可以使用itertools.chain

for myObj in itertools.chain.from_iterable(L):
  myObj.attr = 0

但是,我想知道我是否可以将所有内容都放在一行中。我可以使用类似生成器的结构来做到这一点吗?类似于以下内容:

(myObj.attr=0 for subl in L for myObj in subl)

现在这不会真正起作用,并且会引发 SyntaxError,但有可能发生类似的事情吗?

4

3 回答 3

1

这是对生成器表达式的滥用,但是:

any(setattr(obj, "attr", 0) for sub in L for obj in sub)

或者,可能会稍微快一些,因为没有对每个对象进行测试:

from collections import deque
do = deque(maxlen=0).extend

do(setattr(obj, "attr", 0) for sub in L for obj in sub)
于 2013-10-31T04:33:58.467 回答
1

看这个例子:

class C:
def __init__(self):
        self.a = None
    def f(self, para):
        self.a = para

list1 = [C() for e in range(3)]
list2 = [C() for e in range(3)]
list3 = [list1, list2]

[c.f(5) for l in list3 for c in l]

for e in list3:
    for c in e:
        print c.a

结论

您可以创建一个方法来设置属性。它看起来像:

[myObj.setattr(0) for subl in L for myObj in subl]

注意括号

于 2013-10-31T04:35:10.477 回答
1

这是一个简单的解决方案,突然出现在我的脑海中。

使用内置的setattr,您的建议 - itertools.chain.from_iterable- 以及滥用列表理解:

class Foo():
    def __init__(self):
        my_attr = 10
A = Foo()
B = Foo()
C = Foo()
D = Foo()

obj_list = [[A, B], [C, D]]
a = [setattr(obj, "my_attr", 0) for obj in itertools.chain.from_iterable(obj_list)]

结果:

>>> a
[None, None, None, None]
>>> A.my_attr
0
>>> B.my_attr
0
>>> C.my_attr
0
>>> D.my_attr
0

我发现setattr对于这样的情况非常有用,它简单、简短且有效。

希望这可以帮助!

于 2013-10-31T04:38:10.043 回答