我想在一个长度相等的列表字典中来回切换:
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}]
对于那些喜欢巧妙/狡猾的一行代码的人。
这里是从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
(每个字典中的所有键不相同):
common_keys = set.intersection(*map(set, LD))
v = {k: [dic[k] for dic in LD] for k in common_keys}
print(v)
如果您被允许使用外部包,Pandas非常适合这个任务:
import pandas as pd
pd.DataFrame(DL).to_dict(orient="records")
输出结果为:
[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
您还可以使用orient="list"
来恢复原始结构
{'a': [0, 1], 'b': [2, 3]}
{'a': [0, 1], 'b': [2, 3]}
。使用 pd.DataFrame(DL).to_dict('records')
可以达到预期效果。 - ayhan或许考虑使用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
зљ„еЊғ别吗пәџе…·дҢ“жқӨиҮөпәЊдёғ什么第дғЊдёҒдёҚиµ·дҢњз”Ёпәџ - Adam Greenhall从字典列表中获取数据很简单:
您可以使用以下格式:
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())))]
如果你假设所有列表的长度相同,那么你可以简化操作并提高性能,方法如下:
Which, if you assume that all your lists are the same length, you can simplify and gain a performance increase by going to:
ld = [{key:value[index] for key, value in dl.items()}
for index in range(len(dl.values()[0]))]
以下是将其转换回列表字典的方法:
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
,而不是functools.reduce
。dl2 = {key:[item[key] for item in ld] for key in ld[0].keys() }
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')
输出:
[{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
out2 = pd.DataFrame(LD).to_dict('list')
输出:
{'a': [0, 1], 'b': [2, 3]}
DLtoLD(LDtoDL(l))
不再是身份)。
From list to dict
Actually less clean than @dwerk's defaultdict version.
def LDtoDL (l) :
result = {}
for d in l :
for k, v in d.items() :
result[k] = result.get(k,[]) + [v] #inefficient
return result
From dict to list
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
DLtoLD({1: [3], 2: [4, 5]})
的结果是 [{1: 3, 2: 4}, {2: 5}],而我期望的是 [{1: 3, 2: 4}, {1: 3, 2: 5}]... - dsteinhoefel我需要一种适用于不同长度的列表的方法(因此这是原问题的概括)。由于我在这里没有找到任何符合我期望的代码,所以这是我的代码,它对我有效:
def dict_of_lists_to_list_of_dicts(dict_of_lists: Dict[S, List[T]]) -> List[Dict[S, T]]:
keys = list(dict_of_lists.keys())
list_of_values = [dict_of_lists[key] for key in keys]
product = list(itertools.product(*list_of_values))
return [dict(zip(keys, product_elem)) for product_elem in product]
例子:
>>> dict_of_lists_to_list_of_dicts({1: [3], 2: [4, 5]})
[{1: 3, 2: 4}, {1: 3, 2: 5}]
>>> dict_of_lists_to_list_of_dicts({1: [3, 4], 2: [5]})
[{1: 3, 2: 5}, {1: 4, 2: 5}]
>>> dict_of_lists_to_list_of_dicts({1: [3, 4], 2: [5, 6]})
[{1: 3, 2: 5}, {1: 3, 2: 6}, {1: 4, 2: 5}, {1: 4, 2: 6}]
>>> dict_of_lists_to_list_of_dicts({1: [3, 4], 2: [5, 6], 7: [8, 9, 10]})
[{1: 3, 2: 5, 7: 8},
{1: 3, 2: 5, 7: 9},
{1: 3, 2: 5, 7: 10},
{1: 3, 2: 6, 7: 8},
{1: 3, 2: 6, 7: 9},
{1: 3, 2: 6, 7: 10},
{1: 4, 2: 5, 7: 8},
{1: 4, 2: 5, 7: 9},
{1: 4, 2: 5, 7: 10},
{1: 4, 2: 6, 7: 8},
{1: 4, 2: 6, 7: 9},
{1: 4, 2: 6, 7: 10}]
这是我的小脚本:
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) 你假设列表具有相同的长度
R
数据框架。 - Midnighter