获取python字典列表中某个键的所有值

获取python字典列表中某个键的所有值,python,dictionary,Python,Dictionary,我有一个Python列表,其中包含一个“嵌套”字典。因此,我的列表如下所示: List = [{'entry' : {'Name' : 'Smith', 'Age' : 25}}, {'entry' : {'Name' : 'Mary', 'Age' : 28}}] 我想从列表中返回键“Name”的所有值,而不使用循环。因此,如果我使用循环,它就可以工作,因为它适用于列表中的单个条目。例如:List[0]['entry']['Name']工作并返回'Smith'。但是,我需要类似于List[:

我有一个Python列表,其中包含一个“嵌套”字典。因此,我的列表如下所示:

List = [{'entry' : {'Name' : 'Smith', 'Age' : 25}}, {'entry' : {'Name' : 'Mary', 'Age' : 28}}]
我想从列表中返回键“Name”的所有值,而不使用循环。因此,如果我使用循环,它就可以工作,因为它适用于列表中的单个条目。例如:
List[0]['entry']['Name']
工作并返回'Smith'。但是,我需要类似于
List[:]['entry']['Name']
的东西,它应该返回一个包含条目“Smith”和“Mary”的列表。这可能吗?

您可以使用:

 [o['entry']['Name'] for o in List]
结果:[“史密斯”、“玛丽”]

请注意,它仍然是循环。如果没有循环,则无法执行此操作。

您可以与as一起使用:

尽管在这里看不到循环,但在内部
map()
也会在列表上迭代。您不能跳过对列表的迭代以实现您想要的

更好的方法是使用列表理解:

或者,如果嵌套dict中可能缺少任何键,您可以添加筛选器,如下所示:

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

不幸的是,这在python中是不可能的,尽管这将是一个非常有用的特性。类似的功能通常只在特定领域的查询语言中可用(例如,我认为Django ORM支持类似的索引),但在我能想到的任何通用语言中都不可用

你最好的方法是

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

我不知道为什么不能使用循环,但会列出理解工作?让我知道原因,也许我可以推荐其他东西

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

出于好奇,我发布了
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

结论,
列表理解
是最快的方法map返回一个生成器。

由于性能原因,我不想使用循环(为了更快),因为我的实际列表包含数百万个条目。您说,出于性能原因,您不想使用for循环或列表理解,因为您的数据有“数百万”个条目。有多少百万--1100万?如果答案是100万,那么在我的基本台式机上迭代大约需要0.13秒。如果你的答案是1000万或1亿,我建议你需要一个完全不同的策略——数据不一定保存在内存中,数据的存储方式可以让你的主要查询快速得到回答。热爱时间。
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