从字典创建多个列表?

时间:2019-07-20 11:55:07

标签: python-3.x list list-comprehension

我有这样的数据:

d = [{"name":"Matt", "age":10, "state":"NJ"}, {"name":"Jack", "age":8, "state":"NY"}]

我想要三个单独的列表:names, ages, states

这是一种实现方法:

names = [e['name'] for e in d]
ages =  [e['age'] for e in d]
states =  [e['state'] for e in d]

但这需要经过d 3次。

我可以一口气完成所有操作而无需for循环吗?

2 个答案:

答案 0 :(得分:2)

确定可以:

names, ages, states = [[e[name] for e in d] for name in ('name', 'age', 'state')]

假设没有for循环,您实际上是指具有列表理解


仅对于Python原语,您将需要一种或另一种方式进行嵌套循环。 但是,您描述的数据似乎非常适合 tabular 模型。 如果您发现自己经常进行 tabular 操作,最好使用pandas之类的专用工具,例如:

import pandas as pd


d = [{"name":"Matt", "age":10, "state":"NJ"}, {"name":"Jack", "age":8, "state":"NY"}]

df = pd.Dataframe(d)
#    age  name state
# 0   10  Matt    NJ
# 1    8  Jack    NY

df['name']
# 0    Matt
# 1    Jack
# Name: name, dtype: object

请注意,仅未看到单词for并不意味着您实际上没有在循环。 请考虑以下内容:

d = [{"name":"Matt", "age":10, "state":"NJ"}, {"name":"Jack", "age":8, "state":"NY"}]
l = [list(x.values()) for x in d]
# [['Matt', 10, 'NJ'], ['Jack', 8, 'NY']]
names, ages, states = list(zip(*l))

在这里,尽管只有{em}明确地遍历d,但list()的创建实际上却隐藏了额外的遍历。 另一个 hidden 循环伴随着*魔术。 因此,使用上面的代码,您实际上是遍历数据集2次,每次都有2个嵌套循环。 鉴于这些隐藏循环通常更快,对于足够大的数据集,此解决方案将比上面的单行代码慢。

在我的系统中,对于d来说,它们的速度大致相同:

dd = d * 1
%timeit names, ages, states = [[e[name] for e in dd] for name in ('name', 'age', 'state')]
# 1.45 µs ± 9.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit l = [list(x.values()) for x in dd]; names, ages, states = list(zip(*l))
# 1.47 µs ± 19.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

但是对于d大10倍,单线已是大约。两倍快:

dd = d * 10
%timeit names, ages, states = [[e[name] for e in dd] for name in ('name', 'age', 'state')]
# 4.14 µs ± 219 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit l = [list(x.values()) for x in dd]; names, ages, states = list(zip(*l))
# 8.01 µs ± 79.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

最后请注意,如果您可以控制数据的生成方式,并且拥有l之类的列表列表,则list(zip(*l))隐式循环将是比等效的嵌套列表理解要快。

答案 1 :(得分:0)

这一次只进行了ul li.current_page_item > a { color: rgba(255, 0, 0, 1.0); } 次,只是不够优雅:

d