Ich habe eine Liste solcher Diktate:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
Ich will ['apple', 'banana', 'cars']
Was ist der beste Weg, dies zu tun?
Ich habe eine Liste solcher Diktate:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
Ich will ['apple', 'banana', 'cars']
Was ist der beste Weg, dies zu tun?
Antworten:
Angenommen, jedes Diktat hat einen value
Schlüssel, können Sie schreiben (vorausgesetzt, Ihre Liste heißt benannt l
).
[d['value'] for d in l]
Wenn value
möglicherweise fehlt, können Sie verwenden
[d['value'] for d in l if 'value' in d]
Hier ist eine andere Möglichkeit, dies mit den Funktionen map () und lambda zu tun:
>>> map(lambda d: d['value'], l)
wo l ist die Liste. Ich sehe diesen Weg "sexiest", aber ich würde es mit dem Listenverständnis tun.
Update: Falls dieser 'Wert' als Schlüssel fehlt, verwenden Sie:
>>> map(lambda d: d.get('value', 'default value'), l)
Update: Ich bin auch kein großer Fan von Lambdas, ich nenne lieber Dinge ... so würde ich es in diesem Sinne machen:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Ich würde sogar noch weiter gehen und eine einzige Funktion erstellen, die explizit sagt, was ich erreichen möchte:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
map
Verwenden Sie list
in Python 3, da ein Iterator zurückgegeben wird , um eine Liste zurückzugeben, z list(map(operator.itemgetter('value'), l))
.
map
möchten operator.itemgetter('value')
, verwenden Sie nicht a lambda
.
[x['value'] for x in list_of_dicts]
getkey
... meinst du d.get('value')
? Das wäre dasselbe wie @ isbadawis 2. Listenverständnis, nicht das von Michal.
Für einen sehr einfachen Fall wie diesen ist ein Verständnis wie in Ismail Badawis Antwort definitiv der richtige Weg.
Wenn die Dinge jedoch komplizierter werden und Sie mit dem Schreiben von Mehrklauseln oder verschachtelten Verständnissen mit komplexen Ausdrücken beginnen müssen, sollten Sie nach anderen Alternativen suchen. Es gibt verschiedene (quasi) Standardmethoden zum Festlegen von XPath-Suchvorgängen in verschachtelten Diktat- und Listenstrukturen wie JSONPath, DPath und KVC. Und es gibt nette Bibliotheken auf PyPI für sie.
Hier ist ein Beispiel mit der genannten Bibliothek dpath
, das zeigt, wie es etwas etwas komplizierteres vereinfachen kann:
>>> dd = {
... 'fruits': [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}],
... 'vehicles': [{'value': 'cars', 'blah':4}]}
>>> {key: [{'value': d['value']} for d in value] for key, value in dd.items()}
{'fruits': [{'value': 'apple'}, {'value': 'banana'}],
'vehicles': [{'value': 'cars'}]}
>>> dpath.util.search(dd, '*/*/value')
{'fruits': [{'value': 'apple'}, {'value': 'banana'}],
'vehicles': [{'value': 'cars'}]}
Oder mit jsonpath-ng
:
>>> [d['value'] for key, value in dd.items() for d in value]
['apple', 'banana', 'cars']
>>> [m.value for m in jsonpath_ng.parse('*.[*].value').find(dd)]
['apple', 'banana', 'cars']
Dieser sieht auf den ersten Blick möglicherweise nicht ganz so einfach aus, da find
Übereinstimmungsobjekte zurückgegeben werden, die alle Arten von Dingen außer nur dem übereinstimmenden Wert enthalten, z. B. einen Pfad direkt zu jedem Element. Bei komplexeren Ausdrücken kann es jedoch einen großen Unterschied machen , einen Pfad wie '*.[*].value'
anstelle einer Verständnisklausel für jeden anzugeben *
. Außerdem ist JSONPath eine sprachunabhängige Spezifikation, und es gibt sogar Online-Tester , die beim Debuggen sehr praktisch sein können.
Ich denke, so einfach wie unten würde Ihnen geben, wonach Sie suchen.
In[5]: ll = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}]
In[6]: ld = [d.get('value', None) for d in ll]
In[7]: ld
Out[7]: ['apple', 'banana', 'cars']
Sie können dies auch mit einer Kombination aus map
und tun, lambda
aber das Listenverständnis sieht eleganter und pythonischer aus.
Für eine kleinere Eingabeliste ist das Verständnis ein guter Weg, aber wenn die Eingabe wirklich groß ist, sind Generatoren meiner Meinung nach der ideale Weg.
In[11]: gd = (d.get('value', None) for d in ll)
In[12]: gd
Out[12]: <generator object <genexpr> at 0x7f5774568b10>
In[13]: '-'.join(gd)
Out[13]: 'apple-banana-cars'
Hier ist ein Vergleich aller möglichen Lösungen für größere Eingaben
In[2]: l = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}] * 9000000
In[3]: def gen_version():
...: for i in l:
...: yield i.get('value', None)
...:
In[4]: def list_comp_verison():
...: return [i.get('value', None) for i in l]
...:
In[5]: def list_verison():
...: ll = []
...: for i in l:
...: ll.append(i.get('value', None))
...: return ll
In[10]: def map_lambda_version():
...: m = map(lambda i:i.get('value', None), l)
...: return m
...:
In[11]: %timeit gen_version()
172 ns ± 0.393 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In[12]: %timeit map_lambda_version()
203 ns ± 2.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In[13]: %timeit list_comp_verison()
1.61 s ± 20.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In[14]: %timeit list_verison()
2.29 s ± 4.58 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Wie Sie sehen können, sind Generatoren im Vergleich zu den anderen eine bessere Lösung. Die Karte ist im Vergleich zum Generator auch langsamer, da ich es dem OP überlassen werde, dies herauszufinden.
Folge dem Beispiel --
songs = [
{"title": "happy birthday", "playcount": 4},
{"title": "AC/DC", "playcount": 2},
{"title": "Billie Jean", "playcount": 6},
{"title": "Human Touch", "playcount": 3}
]
print("===========================")
print(f'Songs --> {songs} \n')
title = list(map(lambda x : x['title'], songs))
print(f'Print Title --> {title}')
playcount = list(map(lambda x : x['playcount'], songs))
print(f'Print Playcount --> {playcount}')
print (f'Print Sorted playcount --> {sorted(playcount)}')
# Aliter -
print(sorted(list(map(lambda x: x['playcount'],songs))))
Schlüsselwerte aus der Liste der Wörterbücher in Python abrufen?
Ex:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
für d in Daten:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Ausgabe:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}