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?
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?
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)
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]
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)