У мене є список таких диктів:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
я хочу ['apple', 'banana', 'cars']
Який найкращий спосіб зробити це?
У мене є список таких диктів:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
я хочу ['apple', 'banana', 'cars']
Який найкращий спосіб зробити це?
Відповіді:
Якщо припустимо, що кожен дикт має value
ключ, ви можете написати (якщо ваш список названий l
)
[d['value'] for d in l]
Якщо value
може бути відсутнім, ви можете використовувати
[d['value'] for d in l if 'value' in d]
Ось ще один спосіб зробити це за допомогою функції map () та лямбда:
>>> map(lambda d: d['value'], l)
де l - список. Я вважаю цей спосіб "найсексуальнішим", але я би це зробив, використовуючи розуміння списку.
Оновлення: У разі, якщо значення "може" відсутнє як ключове використання:
>>> map(lambda d: d.get('value', 'default value'), l)
Оновлення: Я також не є великим шанувальником лямбдів, я вважаю за краще називати речі ... ось як я це зробив, маючи це на увазі:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Я б навіть пішов далі і створив єдину функцію, яка прямо говорить про те, чого я хочу досягти:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
З Python 3, оскільки map
повертає ітератор, використовуйте list
для повернення списку, наприклад list(map(operator.itemgetter('value'), l))
.
map
, використовуйте operator.itemgetter('value')
, а не a lambda
.
[x['value'] for x in list_of_dicts]
getkey
... ти маєш на увазі d.get('value')
? Це було б так само, як розуміння другого списку @ isbadawi, а не Міхал.
Для дуже простого випадку, як це, розуміння, як у відповіді Ісмаїла Бадаві, безумовно, це шлях.
Але коли справи ускладнюються, і вам потрібно почати писати багатозначні або вкладені розуміння зі складними виразами в них, варто розглянути інші варіанти. Існує кілька різних (квазі-) стандартних способів задати пошук у стилі XPath для вкладених структур dict-and-list, таких як JSONPath, DPath та KVC. І є приємні бібліотеки на PyPI для них.
Ось приклад з назвою бібліотеки dpath
, який показує, як можна спростити щось трохи складніше:
>>> 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'}]}
Або, використовуючи 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']
Цей на перший погляд може виглядати не так просто, тому що find
повертає об'єкти відповідності, які включають всі види речей, окрім лише відповідного значення, наприклад шлях безпосередньо до кожного елемента. Але для більш складних виразів можливість встановлення шляху, як '*.[*].value'
замість пункту розуміння для кожного, *
може призвести до великої зміни. Крім того, JSONPath - це мовно-агностична специфікація, і є навіть онлайн-тестери, які можуть бути дуже зручними для налагодження.
Я думаю, що так просто, як нижче, дасть вам те, що ви шукаєте.
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']
Ви можете зробити це за допомогою комбінації map
та lambda
, але розуміння списку виглядає більш елегантно та пітонічно.
Для меншого списку вхідних даних розуміння - це шлях, але якщо введення дійсно велике, то, я думаю, генератори - ідеальний шлях.
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'
Ось порівняння всіх можливих рішень для більшого введення
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)
Як бачите, генератори є кращим рішенням порівняно з іншими, карта також повільніше порівняно з генератором, тому я залишу до ОП розібратися.
Дотримуйтесь прикладу -
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))))
Отримати ключові значення зі списку словників у python?
Наприклад:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
для d у даних:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Вихід:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}