列表中的词典列表

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单行的人.

这里是DLLD:

v = [dict(zip(DL,t)) for t in zip(*DL.values())]
print(v)
Run Code Online (Sandbox Code Playgroud)

LDDL:

v = {k: [dic[k] for dic in LD] for k in LD[0]}
print(v)
Run Code Online (Sandbox Code Playgroud)

LDDL是有点hackier因为你假设键是在各个相同dict.此外,请注意,我不容忍在任何类型的真实系统中使用此类代码.

  • 我不认为你的代码尊重键的顺序. (4认同)
  • @GillBates 你是对的;代码 LD->DL 代码依赖于所有 dicts 以相同的方式排序,这是一个可怕的假设。我已经替换了错误的代码。 (3认同)
  • LD 到 DL 返回元组而不是列表,这可能更理想,也可能不理想。顺便说一句,非常好用的oneliners (2认同)

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)

  • 这可能是版本问题,但上面在pandas 0.18.1中返回`{'a':[0,1],'b':[2,3]}`.`pd.DataFrame(DL).to_dict('records')`的工作原理如上所述. (4认同)

小智 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)

  • 回滚到版本 4 的意义何在?请注意,您将第二个代码片段中的范围弄错了,并且删除 python 代码格式会使代码变得更糟。 (2认同)

Tom*_*Tom 6

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)


piR*_*red 6

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)

非cython版本

文档

from toolz.dicttoolz import merge_with

merge_with(list, *LD)

{'a': [0, 1], 'b': [2, 3]}
Run Code Online (Sandbox Code Playgroud)