【问题标题】:use multiple keys in a list to iterate over a list of dictionaries使用列表中的多个键来遍历字典列表
【发布时间】:2019-10-01 00:47:41
【问题描述】:

我有一个list 的字典。从每个字典中,我想提取我预先保存在列表中的一些键的信息。 我可以用for-loop 来做到这一点,但我的list 长度是 15,504,603。它需要很长时间来处理。我正在寻找替代方法。

我的字典列表(实际上是query_set.QuerySet):

data = [
{'name': 'Alex', 'employee_id': 1110, 'age': 38, 'rank': 'CEO', 'salary': 'unknown'},
{'name': 'Monty', 'employee_id': 1111, 'age': 33, 'rank': 'EO', 'salary': 2400},
{'name': 'John', 'employee_id': 1114, 'age': 32, 'rank': 'EO', 'salary': 2200},
{'name': 'Max', 'employee_id': 1120, 'age': 26, 'rank': 'OA', 'salary': 1200},
{'name': 'Ginee', 'employee_id': 1130, 'age': 28, 'rank': 'OA', 'salary': 1200},
{'name': 'Adam', 'employee_id': None, 'age': 18, 'rank': 'summer_intern', 'salary': None}
]

我要提取的信息是'name''age''rank' 所以我事先列出了一个键列表:

info = ['name', 'age', 'rank']

我可以通过执行 for 循环来完成任务

result = []
result.append(info)
for i in range(len(data)):
    output = [data[i][x] for x in info]
    result.append(output)

最后

for item in result:
    print("\t".join(map(str,(item))))

结果如下:

name    age rank
Alex    38  CEO
Monty   33  EO
John    32  EO
Max 26  OA
Ginee   28  OA
Adam    18  summer_intern

实际上,我的列表中有 15504603 个字典,其中 43 个 key : value 需要很长时间才能处理。即运行约 2 小时后的 22661/15504603。

理想的省时的方法是什么?

【问题讨论】:

  • 打印速度变慢了。
  • @BrendanAbel 不,伙计,我在这个进度条的for i in tqdm(range(len(data))): 中使用tqdm 进度条我可以说它在这一步被延迟了。

标签: python python-3.x dictionary iterator


【解决方案1】:

如果你想使用熊猫

import pandas as pd
df = pd.DataFrame(data)
df1 = df.loc[:,['name', 'age', 'rank']]

【讨论】:

  • 成功了。此外,我使用了df = pd.DataFrame(list(queryset)),因为我的数据是QuerySetfound here。但是,您是否知道如何为此操作添加进度条,即tqdm
  • 我想这个答案stackoverflow.com/a/34365537/5684634 可能会对你有所帮助。感谢您是否也可以支持我的回答。如果你能接受我的回答,两声欢呼。
  • 我是新用户,我还不能投票。 :( 但是,stackoverflow.com/a/34365537/5684634 我自己发现了这个,对像我这样的新手没有帮助。:(
【解决方案2】:

试试operator.itemgetter

list(map(operator.itemgetter(*info), data))

输出:

[('Alex', 38, 'CEO'),
 ('Monty', 33, 'EO'),
 ('John', 32, 'EO'),
 ('Max', 26, 'OA'),
 ('Ginee', 28, 'OA'),
 ('Adam', 18, 'summer_intern')]

这比原来的循环快了大约 6 倍:

test = data * 10000
# Given 60,000 dict

%%timeit

result = []
result.append(info)
for i in range(len(test)):
    output = [test[i][x] for x in info]
    result.append(output)
# 36.6 ms ± 314 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit list(map(operator.itemgetter(*info), test))
# 6.92 ms ± 32.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

  • 这个与answer from@Vasu Devan 完美配合。但是,在for循环中我可以添加一个带有tqdm的进度条,在这种情况下我应该如何添加一个进度条呢?
【解决方案3】:

使您的代码变慢的主要原因是您正在构建一个巨大的、占用内存的列表,只是为了进行迭代。您应该在迭代字典列表时直接逐行打印输出:

print(*info, sep='\t')
for record in data:
    print(*(record[key] for key in info), sep='\t')

【讨论】:

    猜你喜欢
    • 2019-06-04
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多