13

我想将一个函数应用于列表中的所有元素,但我想实际更改元素(它们是对象),而不是查看结果。我认为这是使用map()或列表推导的问题。

class Thing(object):
    pass

# some collection of things
my_things

# they are all big...

# produces SyntaxError: invalid syntax
[i.size = "big" for i in my_things]

# produces SyntaxError: lambda cannot contain assignment
map(lambda i: i.size="big", [i for i in my_things]) 

# no error, but is it the preferred way?
for i in my_things:
    i.size="big"

这样做的方法是什么?

4

5 回答 5

17

有什么问题

for i in my_things:
    i.size = "big"

您既不想使用也不想使用map列表理解,因为它们实际上会创建新列表。而且你不需要那个开销,是吗?

于 2012-05-11T15:45:29.187 回答
11

虽然我同意没有任何问题

for i in my_things:
    i.size = "big"

有些人对 python 单线很感兴趣。;)

一种选择是向您的类添加一个 set 方法,然后可以从 lambda 调用该方法(本质上是将赋值隐藏在函数中):

class Thing(object):
    def setSize(self, size):
        self.size = size

map(lambda i: i.setSize("big"), my_things) 
于 2012-05-11T16:02:43.017 回答
2

您可以使用该__setattr__方法在列表理解中分配属性。虽然,根据一些 SO 线程,使用列表推导而不使用输出不是 Pythonic。

[i.__setattr__('size', 'big') for i in my_things]
于 2012-05-11T15:57:03.797 回答
1

我认为这是使用 map() 或列表推导的问题。

不是完全。

my_things[:] = map(...)
于 2012-05-11T15:38:25.710 回答
0

在 python3 上可能是这样的:

[dict(**i.__dict__, size='big') for i in my_things]

或者

map(lambda x: dict(**x.__dict__, size='big'), my_things)

如果我是 dict 不是对象

[dict(**i, size='big') for i in my_things]

在 python2 上

[dict(i.copy(), size='big') for i in my_things]  # isinstance(i, dict)
[dict(i.__dict__.copy(), size='big') for i in my_things]  # isinstance(i, object)
于 2016-08-17T03:55:06.753 回答