2016-05-18 7 views
4

Sagen wir, ich habe eine Liste der Wörterbücher:Return-Wörterbuch mit einem geänderten Element

>>> d = [{'a': 2, 'b': 3, 'c': 4}, {'a': 5, 'b': 6, 'c': 7}] 

Und ich will eine Karte Operation auszuführen, wo ich in jedem Wörterbuch nur einen Wert ändern. Eine Möglichkeit, das zu tun, ist ein neues Wörterbuch zu erstellen, die einfach die ursprünglichen Werte enthalten zusammen mit den verändert denjenigen:

>>> map(lambda x: {'a': x['a'], 'b': x['b'] + 1, 'c': x['c']}, d) 
[{'a': 2, 'c': 4, 'b': 4}, {'a': 5, 'c': 7, 'b': 7}] 

Dies kann widerspenstig, wenn die Wörterbücher haben viele Einzelteile.

Eine weitere Möglichkeit könnte sein, eine Funktion zu definieren, die Kopien der Original Wörterbuch und nur die gewünschten Werte verändert:

>>> def change_b(x): 
...  new_x = x.copy() 
...  new_x['b'] = x['b'] + 1 
...  return new_x 
... 
>>> map(change_b, d) 
[{'a': 2, 'c': 4, 'b': 4}, {'a': 5, 'c': 7, 'b': 7}] 

Dies erfordert jedoch eine eigene Funktion zu schreiben und verliert die Eleganz eines Lambda-Ausdruck.

Gibt es einen besseren Weg?

Antwort

4

Dies funktioniert (und ist kompatibel mit python2 und python3):

>>> map(lambda x: dict(x, b=x['b']+1), d) 
[{'a': 2, 'c': 4, 'b': 4}, {'a': 5, 'c': 7, 'b': 7}] 

das gesagt ist, glaube ich, dass mehr als oft nicht, sind lambda basierte Lösungen weniger elegant als
nicht lambda Gegenstücke ... Der Grund für diese Aussage ist, dass ich sofort die von Ihnen vorgeschlagene Lösung betrachten kann und ich weiß genau, was sie tut. Die lambda basierte Lösung, die ich würde nur schrieb ein bisschen zu denken mehr Denken zu analysieren und dann tatsächlich zu verstehen ...

Obwohl map werden Sie auf python3.x ein iterable Objekt geben, dass isn 't eine Liste ...

1

Sie können eine for Schleife mit einem update Aufruf verwenden. Hier ist ein Hacky Einzeiler:

dcts = [{'a': 2, 'b': 3, 'c': 4}, {'a': 5, 'b': 6, 'c': 7}] 
dcts = [d.update({'b': d['b']+1}) or d for d in dcts] 

Edit: Um original dicts zu erhalten:

from copy import copy 
dcts = [d.update({'b': d['b']+1}) or d for d in map(copy, dcts)] 
+1

Dies ändert das Original 'd'. –

3

zunächst eine Funktion zu schreiben scheint nicht, dass unelegant mir an erster Stelle. Das heißt, willkommen in der schönen neuen Welt der Python 3.5 und PEP 448:

>>> d = [{'a': 2, 'b': 3, 'c': 4}, {'a': 5, 'b': 6, 'c': 7}] 
>>> d 
[{'b': 3, 'a': 2, 'c': 4}, {'b': 6, 'a': 5, 'c': 7}] 
>>> [{**x, 'b': x['b']+1} for x in d] 
[{'b': 4, 'a': 2, 'c': 4}, {'b': 7, 'a': 5, 'c': 7}] 

Von wie Ihr map verhält, dann ist es klar, dass man 2 verwenden, aber das ist leicht genug, um zu beheben. :-)

Verwandte Themen