2012-05-11 46 views
10

我想將一個函數應用於列表中的所有元素,但我想實際更改元素(它是對象),而不是查看結果。我認爲這是使用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" 

這樣做的方法是什麼?

回答

13

的,什麼是錯

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

你不想使用既不map也不名單comprehansion因爲他們實際上創造新的名單。你不需要那些開銷,是嗎?

+0

我不知道地圖製作一個新的列表,這是提高一些眉毛。 – lukecampbell

+0

@lukecampbell它必須。 :)考慮這個例子:'x = [ - 1,1]'和'map(lambda i:i> 0,x)'。然後再看看'x'。它根本沒有改變。 'Map'創建了新的列表。它總是如此。 – freakish

+0

地圖是否會創建新列表?我不敢相信我沒有考慮過這個。 – cammil

1

我認爲這是使用map()或列表解析的問題。

不完全是。

my_things[:] = map(...) 
1

您可以使用__setattr__方法在列表理解中分配屬性。儘管根據一些SO線程,使用列表推導而不使用輸出並不是pythonic。

[i.__setattr__('size', 'big') for i in my_things] 
9

雖然我同意,有什麼錯

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

有些人是熱成蟒蛇單行。 ;)

一種選擇是一套方法添加到您的類,然後可以從拉姆達稱爲(實質上隱藏在一個函數賦值):上python3

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

map(lambda i: i.setSize("big"), my_things) 
+1

這仍然創建一個新的列表! –

+0

的確如此,但那不是要求。鑑於對象的引用性質,它也會改變原始列表中的對象。 – DirkR

0

也許是這樣的:

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

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

如果i是字典不反對

[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) 
相關問題