Python 目录列表到/从目录列表列表
我希望在列表字典(长度相同)之间来回切换: 以及字典列表:Python 目录列表到/从目录列表列表,python,list,dictionary,Python,List,Dictionary,我希望在列表字典(长度相同)之间来回切换: 以及字典列表: LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}] 我正在寻找最干净的方法来切换这两种形式。 < P>也许考虑使用NUMPY: import numpy as np arr = np.array([(0, 2), (1, 3)], dtype=[('a', int), ('b', int)]) print(arr) # [(0, 2) (1, 3)] 在这里,我们访问按名称索引的列,例如'a',或'
LD = [{'a': 0, 'b': 2}, {'a': 1, 'b': 3}]
我正在寻找最干净的方法来切换这两种形式。 < P>也许考虑使用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
):
这里我们通过整数索引访问行(有点像LD
):
行中的每个值都可以通过列名访问(类似于LD
):
下面是我的小脚本:
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)假设列表的长度相同如果不介意使用生成器,可以使用
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
由于技术原因,它并不像它可能的那样“干净”:我最初的实现的确产生了dict(…)
,但这最终成为了一个空字典,因为(在Python 2.5中)c中b的a
在迭代c
时不区分停止迭代异常和计算a
时的停止迭代异常
另一方面,我不知道你到底想做什么;设计一个满足您需求的数据结构,而不是试图将其固定在现有的数据结构中,可能更明智。(例如,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]}
或使用:
走另一条路是有问题的。您需要从字典中的键向列表中提供一些插入顺序的信息。回想一下,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]}]
如果你的问题是出于好奇,那么这就是你的答案。如果您有实际问题,我建议您重新考虑数据结构。这两种解决方案似乎都不是一个非常可扩展的解决方案 夏天的星期五是我能想到的最干净的方式。作为奖励,它支持不同长度的列表(但在本例中,
dltell(LDtoDL(l))
不再是标识)
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
以下是我提出的一行解决方案(为了可读性,将其分散在多行上): 如果dl是列表的原始目录:
dl = {"a":[0, 1],"b":[2, 3]}
下面是如何将其转换为dicts列表:
ld=[{key:value[index]表示键,dl.items()中的值]
对于范围内的索引(最大值(映射(len,dl.values()))]
如果假设所有列表的长度相同,则可以通过以下步骤简化并提高性能:
ld=[{key:value[index]表示键,dl.items()中的值]
对于范围内的索引(len(dl.values()[0]))
如果dl
包含不对称列表,则以下工作正常:
来自itertools导入产品的
dl={“a”:[0,1],“b”:[2,3,4],“c”:[5,6,7,8]}
ld=[dict(zip(dl.keys(),items))
对于产品(*(dl.values())中的项目]
下面是如何将其转换为列表的dict:
dl = {"a":[0, 1],"b":[2, 3]}
dl2={key:[ld中的项的项[key]
对于输入列表(functools.reduce(
λx,y:x.union(y),
(设置(dicts.keys())用于ld中的dicts)
))
}
如果您使用的是Python2而不是Python3,那么您可以使用reduce
而不是functools.reduce
如果假设列表中的所有dict都具有相同的键,则可以简化此操作:
dl2 = {key:[item[key] for item in ld] for key in ld[0].keys() }
如果允许您使用外部软件包,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]}
对于那些喜欢聪明/老套的一句话的人 这是从
DL
到LD
:
print(arr[0])
# (0, 2)
print(arr[0]['b'])
# 2
v = [dict(zip(DL,t)) for t in zip(*DL.values())]
print(v)
和LD
至DL
:
print(arr['a'])
# [0 1]
v = {k: [dic[k] for dic in LD] for k in LD[0]}
print(v)
LD
到DL
有点不太正常,因为您假设每个dict
中的键都是相同的。另外,请注意,我不允许在任何类型的实际系统中使用此类代码。熊猫的python模块可以为您提供易于理解的解决方案。作为对@chiang答案的补充,D-to-L和L-to-D的解决方案如下:
cytoolz.dicttoolz.merge_与
非cython版本
以下是一个不使用任何库的解决方案:
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}]
DL={'a':[0,1,2,3],'b':[2,3,4,5]}
LD=[{'a':0,'b':2},{'a':1,'b':3}]
空_列表=[]
空_dict={}
#在词汇表的值中查找列表的长度
len_list=0
对于DL.values()中的i:
如果len_列表
不清楚您将如何解释DL的顺序?也就是说,如果有许多元素,它们就会失去插入顺序。如果“a”和“b”以不同的顺序从DL中出现,那么产生的LD的顺序应该是什么?好的建议delnan和drewk,谢谢。我正在从CSV文件导入数据,其中列的顺序无关紧要。@AdamGreenhall由于您正在使用CSV文件,我强烈建议您尝试一下。这有点像类固醇上的数据帧。你能解释一下将[(0,2)、(1,3)]
和[[0,2],[1,3]]
传递到np.array
之间的区别吗?亚当·格林霍尔:你问了一个很好的问题。我不知道完整的答案。我知道numpy有时比Python更能区分列表和元组。T
from cytoolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
from toolz.dicttoolz import merge_with
merge_with(list, *LD)
{'a': [0, 1], 'b': [2, 3]}
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}]
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