Ada*_*all 57 python dictionary list
我希望在列表字典(所有相同长度)之间来回切换:
DL = {'a': [0, 1], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)
和一个词典列表:
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
Run Code Online (Sandbox Code Playgroud)
我正在寻找在两种形式之间切换的最干净的方法.
小智 62
对于那些喜欢聪明/ hacky单行的人.
这里是DL
要LD
:
v = [dict(zip(DL,t)) for t in zip(*DL.values())]
print(v)
Run Code Online (Sandbox Code Playgroud)
并LD
到DL
:
v = {k: [dic[k] for dic in LD] for k in LD[0]}
print(v)
Run Code Online (Sandbox Code Playgroud)
LD
到DL
是有点hackier因为你假设键是在各个相同dict
.此外,请注意,我不容忍在任何类型的真实系统中使用此类代码.
daw*_*awg 12
要从词典列表中删除,它很简单:
您可以使用此表单:
DL={'a':[0,1],'b':[2,3], 'c':[4,5]}
LD=[{'a':0,'b':2, 'c':4},{'a':1,'b':3, 'c':5}]
nd={}
for d in LD:
for k,v in d.items():
try:
nd[k].append(v)
except KeyError:
nd[k]=[v]
print nd
#{'a': [0, 1], 'c': [4, 5], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)
或者使用defaultdict:
nd=cl.defaultdict(list)
for d in LD:
for key,val in d.items():
nd[key].append(val)
print dict(nd.items())
#{'a': [0, 1], 'c': [4, 5], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)
走另一条路是有问题的.您需要从字典中的键中将插入顺序的一些信息放入列表中.回想一下,dict中键的顺序不一定与原始的插入顺序相同.
对于咯咯笑声,假设插入顺序基于排序键.然后你可以这样做:
nl=[]
nl_index=[]
for k in sorted(DL.keys()):
nl.append({k:[]})
nl_index.append(k)
for key,l in DL.items():
for item in l:
nl[nl_index.index(key)][key].append(item)
print nl
#[{'a': [0, 1]}, {'b': [2, 3]}, {'c': [4, 5]}]
Run Code Online (Sandbox Code Playgroud)
如果你的问题是基于好奇心,那就有你的答案.如果您遇到实际问题,请允许我建议您重新考虑数据结构.这些似乎都不是一个非常可扩展的解决方案.
unu*_*tbu 11
也许考虑使用numpy:
import numpy as np
arr = np.array([(0, 2), (1, 3)], dtype=[('a', int), ('b', int)])
print(arr)
# [(0, 2) (1, 3)]
Run Code Online (Sandbox Code Playgroud)
在这里,我们访问由名称索引的列,例如'a'
,或'b'
(有点像DL
):
print(arr['a'])
# [0 1]
Run Code Online (Sandbox Code Playgroud)
这里我们通过整数索引访问行(类似LD
):
print(arr[0])
# (0, 2)
Run Code Online (Sandbox Code Playgroud)
可以通过列名访问行中的每个值(类似LD
):
print(arr[0]['b'])
# 2
Run Code Online (Sandbox Code Playgroud)
eri*_*ang 11
如果您被允许使用外部包,Pandas非常适合这样:
import pandas as pd
pd.DataFrame(DL).to_dict('list')
Run Code Online (Sandbox Code Playgroud)
哪个输出:
[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
Run Code Online (Sandbox Code Playgroud)
小智 7
以下是我提出的单行解决方案(分布在多行以便于阅读):
如果dl是你原来的列表词典:
dl = {"a":[0, 1],"b":[2, 3]}
Run Code Online (Sandbox Code Playgroud)
然后是如何将其转换为dicts列表:
ld = [{key:value[index] for key,value in dl.items()}
for index in range(max(map(len,dl.values())))]
Run Code Online (Sandbox Code Playgroud)
其中,如果您假设所有列表的长度相同,则可以通过以下方式简化并提高性能:
ld = [{key:value[index] for key, value in dl.items()}
for index in range(len(dl.values()[0]))]
Run Code Online (Sandbox Code Playgroud)
以下是如何将其转换回列表的字典:
from itertools import product
dl = {"a":[0, 1],"b":[2, 3, 4], "c":[5, 6, 7, 8]}
ld = [dict(zip(dl.keys(), items))
for items in product(*(dl.values()))]
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Python 2而不是Python 3,那么您可以使用它dl
代替reduce
那里.
如果您假设列表中的所有dicts都具有相同的键,则可以简化此操作:
dl2 = {key:[item[key] for item in ld]
for key in list(functools.reduce(
lambda x, y: x.union(y),
(set(dicts.keys()) for dicts in ld)
))
}
Run Code Online (Sandbox Code Playgroud)
python 模块pandas
可以为您提供一个易于理解的解决方案。作为对@chiang答案的补充,D-to-L和L-to-D的解决方案如下:
import pandas as pd
DL = {'a': [0, 1], 'b': [2, 3]}
out1 = pd.DataFrame(DL).to_dict('records')
Run Code Online (Sandbox Code Playgroud)
输出:
[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
Run Code Online (Sandbox Code Playgroud)
在另一个方向:
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
out2 = pd.DataFrame(LD).to_dict('list')
Run Code Online (Sandbox Code Playgroud)
输出:
{'a': [0, 1], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)
cytoolz.dicttoolz.merge_with
from cytoolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)
from toolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)