Mam listę takich nakazów:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
chcę ['apple', 'banana', 'cars']
Jak najlepiej to zrobić?
Mam listę takich nakazów:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
chcę ['apple', 'banana', 'cars']
Jak najlepiej to zrobić?
Odpowiedzi:
Zakładając, że każdy dykt ma value
klucz, możesz pisać (zakładając, że twoja lista jest nazwana l
)
[d['value'] for d in l]
Jeśli value
brakuje, możesz użyć
[d['value'] for d in l if 'value' in d]
Oto inny sposób na zrobienie tego za pomocą funkcji map () i lambda:
>>> map(lambda d: d['value'], l)
gdzie ja jest listą. Uważam, że ten sposób jest „najseksowniejszy”, ale zrobiłbym to za pomocą rozumienia list.
Aktualizacja: w przypadku, gdy brakuje tej „wartości” jako klucza:
>>> map(lambda d: d.get('value', 'default value'), l)
Aktualizacja: Nie jestem też wielkim fanem lambd, wolę nazywać rzeczy ... tak bym to zrobił mając to na uwadze:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Poszedłbym nawet dalej i stworzył jedyną funkcję, która wyraźnie określa, co chcę osiągnąć:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
W Pythonie 3, ponieważ map
zwraca iterator, użyj, list
aby zwrócić listę, np list(map(operator.itemgetter('value'), l))
.
map
, użyj operator.itemgetter('value')
, a nie pliku lambda
.
[x['value'] for x in list_of_dicts]
getkey
… masz na myśli d.get('value')
? To byłoby to samo, co rozumienie drugiej listy @ isbadawi, a nie Michała.
W bardzo prostym przypadku, takim jak ten, zrozumienie, jak w przypadku odpowiedzi Ismaila Badawiego, jest zdecydowanie właściwą drogą.
Ale kiedy sprawy stają się bardziej skomplikowane i musisz zacząć pisać złożone zdania składające się z wielu zdań lub wyrażenia zagnieżdżone, w których występują złożone wyrażenia, warto przyjrzeć się innym alternatywom. Istnieje kilka różnych (quasi-) standardowych sposobów określania wyszukiwań w stylu XPath w zagnieżdżonych strukturach dyktowania i listy, takich jak JSONPath, DPath i KVC. Są dla nich fajne biblioteki na PyPI.
Oto przykład z biblioteką o nazwie dpath
, pokazujący, jak może uprościć coś nieco bardziej skomplikowanego:
>>> 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'}]}
Lub używając 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']
Ten na pierwszy rzut oka może nie wyglądać tak prosto, ponieważ find
zwraca dopasowywanie obiektów, które zawierają wszelkiego rodzaju rzeczy oprócz tylko dopasowanej wartości, takie jak ścieżka bezpośrednio do każdego elementu. Ale w przypadku bardziej złożonych wyrażeń możliwość określenia ścieżki, takiej jak '*.[*].value'
zamiast klauzuli ze zrozumieniem dla każdego, *
może mieć duże znaczenie. Ponadto JSONPath to specyfikacja niezależna od języka, a nawet testerzy online mogą być bardzo przydatni do debugowania.
Myślę, że tak proste, jak poniżej, dałoby ci to, czego szukasz.
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']
Możesz to zrobić za pomocą kombinacji map
i, lambda
ale rozumienie listy wygląda bardziej elegancko i pytonicznie.
W przypadku mniejszych list wejściowych dobrze jest zrobić, ale jeśli dane wejściowe są naprawdę duże, myślę, że generatory są idealnym sposobem.
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'
Oto porównanie wszystkich możliwych rozwiązań dla większego wkładu
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)
Jak widać, generatory są lepszym rozwiązaniem w porównaniu do innych, mapa jest również wolniejsza w porównaniu do generatora, dlatego pozostawię OP, aby się dowiedzieć.
Podążaj za przykładem --
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))))
Pobrać kluczowe wartości z listy słowników w Pythonie?
Dawny:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
dla d w danych:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Wynik:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}