Saya punya daftar dicts seperti ini:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
saya ingin ['apple', 'banana', 'cars']
Apa cara terbaik untuk melakukan ini?
Saya punya daftar dicts seperti ini:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
saya ingin ['apple', 'banana', 'cars']
Apa cara terbaik untuk melakukan ini?
Jawaban:
Anggap setiap dikt memiliki value
kunci, Anda dapat menulis (dengan asumsi daftar Anda dinamai l
)
[d['value'] for d in l]
Jika value
mungkin hilang, Anda bisa menggunakan
[d['value'] for d in l if 'value' in d]
[d.value for d in l]
terima kasih :)
Berikut cara lain untuk melakukannya menggunakan fungsi map () dan lambda:
>>> map(lambda d: d['value'], l)
dimana l adalah daftarnya. Saya melihat ini "paling seksi", tetapi saya akan melakukannya dengan menggunakan daftar pemahaman.
Pembaruan: Seandainya 'nilai' mungkin hilang sebagai penggunaan utama:
>>> map(lambda d: d.get('value', 'default value'), l)
Update: Saya juga bukan penggemar lambdas, saya lebih suka menyebutkan beberapa hal ... ini adalah bagaimana saya akan melakukannya dengan itu dalam pikiran:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Saya bahkan akan melangkah lebih jauh dan membuat satu-satunya fungsi yang secara eksplisit mengatakan apa yang ingin saya capai:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
Dengan Python 3, sejak map
mengembalikan sebuah iterator, gunakan list
untuk mengembalikan daftar, misalnya list(map(operator.itemgetter('value'), l))
.
map
, gunakan operator.itemgetter('value')
, bukan a lambda
.
[x['value'] for x in list_of_dicts]
getkey
.. maksud Anda d.get('value')
? Itu akan sama dengan pemahaman daftar ke-2 @ isbadawi, bukan pemahaman Michal.
Untuk kasus yang sangat sederhana seperti ini, pemahaman, seperti dalam jawaban Ismail Badawi jelas merupakan jalan yang harus ditempuh.
Tetapi ketika segala sesuatunya menjadi lebih rumit, dan Anda perlu mulai menulis multi-klausa atau pemahaman bersarang dengan ekspresi kompleks di dalamnya, ada baiknya mencari alternatif lain. Ada beberapa cara standar (kuasi) untuk menentukan pencarian gaya XPath pada struktur dict-and-list bersarang, seperti JSONPath, DPath, dan KVC. Dan ada perpustakaan bagus di PyPI untuk mereka.
Berikut ini contoh dengan nama perpustakaan dpath
, yang menunjukkan bagaimana perpustakaan dapat menyederhanakan sesuatu yang sedikit lebih rumit:
>>> 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'}]}
Atau, menggunakan 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']
Yang satu ini mungkin tidak terlihat sesederhana pada pandangan pertama, karena find
mengembalikan objek yang cocok, yang mencakup semua jenis hal selain hanya nilai yang cocok, seperti jalur langsung ke setiap item. Tetapi untuk ekspresi yang lebih kompleks, bisa menentukan jalan seperti '*.[*].value'
bukannya klausa pemahaman untuk masing-masing *
dapat membuat perbedaan besar. Plus, JSONPath adalah spesifikasi bahasa-agnostik, dan bahkan ada penguji online yang bisa sangat berguna untuk debugging.
Saya pikir sesederhana di bawah ini akan memberi Anda apa yang Anda cari.
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']
Anda dapat melakukan ini dengan kombinasi map
danlambda
juga tetapi daftar pemahaman terlihat lebih elegan dan pythonic.
Untuk pemahaman daftar input yang lebih kecil adalah cara untuk pergi tetapi jika input benar-benar besar maka saya kira generator adalah cara yang ideal.
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'
Berikut ini adalah perbandingan dari semua solusi yang mungkin untuk input yang lebih besar
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)
Seperti yang Anda lihat, generator adalah solusi yang lebih baik dibandingkan dengan yang lain, peta juga lebih lambat dibandingkan dengan generator karena alasan saya akan menyerahkan OP untuk mencari tahu.
Ikuti contohnya --
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))))
Dapatkan nilai kunci dari daftar kamus dengan python?
Ex:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
untuk d dalam data:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Keluaran:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}