2016-11-24 14 views
2

私はPythonの中に "入れ子になった"辞書を含むリストを持っています。だから、私のリストは次のようになります:Pythonの辞書リストで特定のキーの値をすべて取得する

ループを使わずに私のリストからキー '名前'のすべての値を返したいと思います。したがって、ループを使用すると、これはリストの1つのエントリで機能するので機能します。たとえば、List[0]['entry']['Name']が動作し、 'Smith'が返されます。しかし、List[:]['entry']['Name']のようなものが必要です。リストには「Smith」と「Mary」という項目が含まれていなければなりません。これは可能ですか?

+0

データに「何百万」ものエントリがあるため、パフォーマンス上の理由からfor-loopやlist comprehensionを使用したくないと言います。何百万、何千、何百万?答えが100万の場合、その反復は私の基本的なデスクトップマシンで約0.13秒かかります。あなたの答えが1000万〜10000万であれば、データが必ずしもメモリに保持されているわけではなく、プライマリクエリに迅速に回答できるようにデータが格納されている場所が必要です。 – FMc

答えて

1

私は好奇心としてreduce()方法を掲示していたが、答えが受け入れられたことから、私はtimeit結果を掲示しています、このチケットの他の回答と掲載結果を比較します。

from timeit import timeit 
import functools 

def _reduce_py2(the_list): 

    return reduce(lambda l, src: l.append(src['entry']['Name']) or l, the_list, []) 

def _reduce_py3(the_list): 

    return functools.reduce(lambda l, src: l.append(src['entry']['Name']) or l, the_list, []) 

def _map_py2(the_list): 

    return map(lambda d: d['entry']['Name'], the_list) 

def _map_py3(the_list): 

    return [i for i in map(lambda d: d['entry']['Name'], the_list)] 

def _list(the_list): 

    return [d['entry']['Name'] for d in the_list] 

the_list = [] 
for i in range(1000): 
    the_list += [{'entry' : {'Name' : 'Smith%s' % i, 'Age' : i}}] 


reps = 1000 

# Compare timings 

print('Reduce:    ', timeit('c(the_list)', 'from __main__ import _reduce_py2 as c, the_list', number=reps)) 
print('Map:     ', timeit('c(the_list)', 'from __main__ import _map_py2 as c, the_list', number=reps)) 
print('List comprehension: ', timeit('c(the_list)', 'from __main__ import _list as c, the_list', number=reps)) 

結果:

Py 2 
Reduce:    0.2090609073638916 
Map:     0.136185884475708 
List comprehension: 0.07403087615966797 

Py 3 
Reduce:    0.20160907896934077 
Map:     0.17127344600157812 
List comprehension: 0.06799810699885711 

結論は、list comprehensionは最速の方法です。しかし、python 3のmapはジェネレータを返します。

2

あなたは使用することができます。

[o['entry']['Name'] for o in List] 

結果:[ 'スミス'、 'メアリー']、それはまだループであることを

注意を。ループなしではこのようなことはできません。また、リストを反復を使用すると、こちらにループが表示されていないにもかかわらず

>>> map(lambda d: d['entry']['Name'], List) 
['Smith', 'Mary'] 

が、内部map()

4

あなたはようmap()lambda expressionを使用することができます。あなたが望むものを達成するためには、リストを反復することはできません。

>>> [d['entry']['Name'] for d in List] 
['Smith', 'Mary'] 

OR、ネストされた辞書に欠けている任意のキーの可能性がある場合、あなたのようにフィルタを追加することができます:

>>> [d['entry']['Name'] for d in List if 'entry' in d and 'Name' in d['entry']] 
['Smith', 'Mary'] 

良い方法はとリストの内包を使用するようになります

2

残念ながら、これは非常に便利な機能ですが、これはPythonでは不可能です。同様の機能は、ドメイン固有のクエリ言語でしか利用できないことがよくあります(たとえば、Django ORMは同様のインデックス作成をサポートしています)。しかし、私が考えることのできる一般的な言語ではありません。

あなたの最善のアプローチは、私はあなたがループを使用することはできませんが、理解の仕事をリストアップする理由はよく分からない

[item['Entry']['Name'] for item in List] 
2

のですか?理由について私に教えてください。おそらく私は他の何かを推薦することができます。

a = [{'entry' : {'Name' : 'Smith', 'Age' : 25}}, {'entry' : {'Name' : 'Mary', 'Age' : 28}}] 
b = [a[i]['entry']['Name'] for i in range(len(a))] 

結果: B = [ 'スミス'、 'メアリー']

+1

私の実際のリストには何百万ものエントリが含まれているので、パフォーマンス上の理由からループを使用したくない(速くするため)。 – mshabeeb

関連する問題