Bunun gibi diktelerin bir listesi var:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
İstiyorum ['apple', 'banana', 'cars']
Bunu yapmanın en iyi yolu nedir?
Bunun gibi diktelerin bir listesi var:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
İstiyorum ['apple', 'banana', 'cars']
Bunu yapmanın en iyi yolu nedir?
Yanıtlar:
Her diktenin bir value
anahtarı olduğunu varsayarsak, yazabilirsiniz (listenizin ismini varsayarak l
)
[d['value'] for d in l]
Eğer value
eksik olabilir, kullanabilirsiniz
[d['value'] for d in l if 'value' in d]
Map () ve lambda işlevlerini kullanarak bunu yapmanın başka bir yolu:
>>> map(lambda d: d['value'], l)
burada l listedir. Bu şekilde "en seksi" görüyorum, ama bunu liste kavrayışını kullanarak yapardım.
Güncelleme: Anahtar değerin 'değer' eksik olması durumunda:
>>> map(lambda d: d.get('value', 'default value'), l)
Güncelleme: Ben de lambdasların büyük bir hayranı değilim, bir şeyleri adlandırmayı tercih ediyorum ... bunu akılda tutarak şöyle yaparım:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Hatta daha ileri gitmek ve açıkça ne elde etmek istediğini söyleyen tek bir işlev oluşturmak:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
Python 3 ile, map
bir yineleyici döndürdüğünden, list
bir liste döndürmek için kullanın , örn list(map(operator.itemgetter('value'), l))
.
map
kullanacaksanız operator.itemgetter('value')
, değil , kullanın lambda
.
[x['value'] for x in list_of_dicts]
getkey
yok .. yani d.get('value')
? Bu, isbadawi'nin Michal'in değil 2. liste kavrayışıyla aynı olurdu.
Bunun gibi çok basit bir durum için, İsmail Badawi'nin cevabında olduğu gibi bir anlayış kesinlikle gidilecek yoldur.
Ancak işler daha karmaşık hale geldiğinde ve içlerinde karmaşık ifadelerle çok yanlı veya iç içe anlayışlar yazmaya başlamanız gerektiğinde, diğer alternatiflere bakmaya değer. JSONPath, DPath ve KVC gibi iç içe geçmiş ve liste yapılarında XPath stili aramaları belirtmenin birkaç farklı (yarı) standart yolu vardır. Ve onlar için PyPI'de güzel kütüphaneler var.
Kitaplık adında dpath
, biraz daha karmaşık bir şeyi nasıl basitleştirebileceğini gösteren bir örnek :
>>> 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'}]}
Veya 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']
Bu, ilk bakışta o kadar basit görünmeyebilir, çünkü find
doğrudan eşleşen değerin yanı sıra her öğeye doğrudan bir yol gibi her türlü şeyi içeren eşleşme nesneleri döndürür. Ancak daha karmaşık ifadeler '*.[*].value'
için, her biri için bir anlama cümlesi yerine bir yol belirleyebilmek *
büyük bir fark yaratabilir. Ayrıca, JSONPath dile bağlı olmayan bir özelliktir ve hata ayıklama için çok kullanışlı olabilecek çevrimiçi test kullanıcıları bile vardır .
Sanırım aşağıdaki kadar basit aradığınızı verecek.
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']
Bunu map
ve kombinasyonuyla da yapabilirsiniz, lambda
ancak liste kavrayışı daha zarif ve pitonik görünür.
Daha küçük bir giriş listesi anlama için gitmek için bir yol ama giriş gerçekten büyükse, o zaman jeneratörler ideal bir yol sanırım.
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'
Daha büyük girdi için olası tüm çözümlerin karşılaştırması
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)
Gördüğünüz gibi, jeneratörler diğerlerine göre daha iyi bir çözümdür, harita da jeneratörle karşılaştırıldığında daha yavaştır, çünkü anlamak için OP'ye bırakacağım.
Örneği takip edin --
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'daki sözlükler listesinden anahtar değerler mi aldınız?
Ör:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
verilerdeki d için:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Çıktı:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}