it-swarm.com.de

Wie wende ich eine Funktion auf Elemente einer Liste an?

Ich möchte eine Funktion auf alle Elemente in der Liste anwenden, aber ich möchte die Elemente (die Objekte sind) tatsächlich ändern, nicht die Ergebnisse anzeigen. Ich denke, dies ist das Problem bei der Verwendung von map() oder Listenverständnissen.

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"

Wie geht das?

12
cammil

Und was ist los mit

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

Sie möchten weder map noch Listenverständnis verwenden, da diese tatsächlich neue Listen erstellen. Und das brauchen Sie nicht, oder?

15
freakish

Ich stimme zwar zu, dass nichts falsch ist 

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

einige Leute sind heiß auf Python-Einzeiler. ;)

Eine Möglichkeit besteht darin, Ihrer Klasse eine set-Methode hinzuzufügen, die dann von Lambda aus aufgerufen werden kann (wodurch die Zuweisung in einer Funktion im Wesentlichen verborgen wird):

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

map(lambda i: i.setSize("big"), my_things) 
11
DirkR

Sie können die __setattr__-Methode verwenden, um das Attribut in einem Listenverständnis zuzuweisen. Laut einigen SO - Threads ist das Verwenden von Listenverstehen ohne Verwendung der Ausgabe nicht Pythonic. 

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

Ich denke, das ist das Problem bei der Verwendung von map () oder Listenverständnissen.

Nicht komplett.

my_things[:] = map(...)

vielleicht so auf python3:

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

oder

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

wenn ich dikt nicht widerspricht

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

auf 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)
0
mackjoner