我希望在列表字典(长度相同)之间来回切换:
DL = {'a': [0, 1], 'b': [2, 3]}
以及字典列表:
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
我正在寻找在两种形式之间切换的最简洁方法。
我希望在列表字典(长度相同)之间来回切换:
DL = {'a': [0, 1], 'b': [2, 3]}
以及字典列表:
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
我正在寻找在两种形式之间切换的最简洁方法。
Answers:
也许考虑使用numpy:
import numpy as np
arr = np.array([(0, 2), (1, 3)], dtype=[('a', int), ('b', int)])
print(arr)
# [(0, 2) (1, 3)]
在这里,我们访问按名称索引的列,例如'a'
或'b'
(类似DL
):
print(arr['a'])
# [0 1]
在这里,我们通过整数索引(类似于LD
)访问行:
print(arr[0])
# (0, 2)
行中的每个值都可以通过列名(类似于LD
)进行访问:
print(arr[0]['b'])
# 2
[(0,2),(1,3)]
和[[0,2],[1,3]]
到之间的区别np.array
吗?具体来说,第二个为什么不起作用?
对于那些喜欢聪明/骇客的单线飞机的人。
这里是DL
要LD
:
v = [dict(zip(DL,t)) for t in zip(*DL.values())]
print(v)
并LD
到DL
:
v = {k: [dic[k] for dic in LD] for k in LD[0]}
print(v)
LD
DL
由于您假设每个密钥都相同,所以to有点黑客dict
。另外,请注意,我不容忍在任何实际系统中使用此类代码。
要从词典列表中查找,很简单:
您可以使用以下形式:
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]}
或使用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]}
走另一条路是有问题的。您需要从字典的键中获得一些有关插入顺序的信息。回想一下,字典中键的顺序不一定与原始插入顺序相同。
对于傻笑,假设插入顺序基于已排序的键。然后,您可以按照以下方式进行操作:
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]}]
如果您的问题是基于好奇心,那么答案就是您。如果您遇到现实问题,请允许我建议您重新考虑数据结构。这些似乎都不是一个非常可扩展的解决方案。
这是我想出的一线解决方案(分布在多行上以提高可读性):
如果dl是列表的原始字典:
dl = {"a":[0, 1],"b":[2, 3]}
然后是将其转换为字典列表的方法:
ld = [{key:value[index] for key,value in dl.items()}
for index in range(max(map(len,dl.values())))]
如果您假设所有列表的长度都相同,则可以通过以下步骤简化并提高性能:
ld = [{key:value[index] for key, value in dl.items()}
for index in range(len(dl.values()[0]))]
如果dl
包含不对称列表,则可以正常工作:
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()))]
将其转换回列表字典的方法如下:
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)
))
}
如果您使用的是Python 2而不是Python 3,则可以直接使用reduce
而不是Python 3 functools.reduce
。
如果您假设列表中的所有字典都具有相同的键,则可以简化此操作:
dl2 = {key:[item[key] for item in ld] for key in ld[0].keys() }
的python模块pandas
可以为您提供一个易于理解的解决方案。作为@chiang答案的补充,D对L和L对D的解决方案如下:
In [1]: import pandas as pd
In [2]: DL = {'a': [0, 1], 'b': [2, 3]}
In [3]: pd.DataFrame(DL).to_dict('records')
Out[3]: [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
In [4]: LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
In [5]: pd.DataFrame(LD).to_dict('list')
Out[5]: {'a': [0, 1], 'b': [2, 3]}
这是我的小脚本:
a = {'a': [0, 1], 'b': [2, 3]}
elem = {}
result = []
for i in a['a']: # (1)
for key, value in a.items():
elem[key] = value[i]
result.append(elem)
elem = {}
print result
我不确定这是不是很好的方法。
(1)您假设清单的长度相同
我可以想到夏季星期五的最干净的方式。另外,它支持不同长度的列表(但在这种情况下,DLtoLD(LDtoDL(l))
不再具有任何标识)。
从列表到字典
实际上不如@dwerk的defaultdict版本干净。
def LDtoDL (l) :
result = {}
for d in l :
for k, v in d.items() :
result[k] = result.get(k,[]) + [v] #inefficient
return result
从字典到列表
def DLtoLD (d) :
if not d :
return []
#reserve as much *distinct* dicts as the longest sequence
result = [{} for i in range(max (map (len, d.values())))]
#fill each dict, one key at a time
for k, seq in d.items() :
for oneDict, oneValue in zip(result, seq) :
oneDict[k] = oneValue
return result
这是不使用任何库的解决方案:
def dl_to_ld(initial):
finalList = []
neededLen = 0
for key in initial:
if(len(initial[key]) > neededLen):
neededLen = len(initial[key])
for i in range(neededLen):
finalList.append({})
for i in range(len(finalList)):
for key in initial:
try:
finalList[i][key] = initial[key][i]
except:
pass
return finalList
您可以这样称呼它:
dl = {'a':[0,1],'b':[2,3]}
print(dl_to_ld(dl))
#[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
如果您不介意发电机,可以使用类似
def f(dl):
l = list((k,v.__iter__()) for k,v in dl.items())
while True:
d = dict((k,i.next()) for k,i in l)
if not d:
break
yield d
由于技术原因,它不是那么“干净”:我的原始实现做到了yield dict(...)
,但这最终成为空字典,因为(在Python 2.5中)a for b in c
在迭代时无法区分StopIteration异常c
与在评估时不能区分StopIteration异常a
。
另一方面,我无法弄清您实际上要做什么。设计满足您要求的数据结构而不是试图将其插入现有数据结构中可能更为明智。(例如,字典列表是表示数据库查询结果的一种不好的方法。)
DL={'a':[0,1,2,3],'b':[2,3,4,5]}
LD=[{'a':0,'b':2},{'a':1,'b':3}]
Empty_list = []
Empty_dict = {}
# to find length of list in values of dictionry
len_list = 0
for i in DL.values():
if len_list < len(i):
len_list = len(i)
for k in range(len_list):
for i,j in DL.items():
Empty_dict[i] = j[k]
Empty_list.append(Empty_dict)
Empty_dict = {}
LD = Empty_list