8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

字典列表至/自列表字典

Excessstone 1月前

77 0

我想在(等长)列表字典之间来回切换: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}]
帖子版权声明 1、本帖标题:字典列表至/自列表字典
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Excessstone在本站《dictionary》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 不清楚您如何解释 DL 的顺序?即,如果您有许多元素,它们会失去插入顺序。如果“a”和“b”以不同的顺序从 DL 中出来,那么生成的 LD 的顺序应该是什么?

  • 也许可以考虑使用 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:你问了一个非常好的问题。我不知道完整的答案。我知道 numpy 有时在列表和元组之间的区分比 Python 要大得多。dtype 语法文档 docs.scipy.org/numpy/docs/numpy.doc.structured_arrays 中说,当使用 \'[l]ist 参数定义 dtype 时...记录结构是用元组列表定义的。\' 但我不知道为什么必须这样。

  • @unutbu 谢谢,非常有趣。我以前没有听说过结构化数组。文档链接现已更改:numpy.org/doc/stable/user/basics.rec.html。此外,我注意到文档中说结构化数组“用于与 C 代码交互以及对结构化缓冲区进行低级操作……希望操作表格数据(例如存储在 csv 文件中的数据)的用户可能会发现其他 pydata 项目更合适,例如 xarray、pandas 或 DataArray。\'

  • 对于那些喜欢巧妙/黑客式的单行代码的人来说。

    以下 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)
    

    另请注意,我不赞成在任何类型的实际系统中使用此类代码。

  • LD 到 DL 返回的是元组而不是列表,这可能更可取,也可能不可取。顺便说一句,非常好用的一个命令

  • @GillBates 您说得对;LD->DL 代码依赖于所有字典以相同的方式排序,这是一个糟糕的假设。我已经替换了错误的代码。

  • 要处理具有不同键的字典:LD[0] 可以被 reduce(set.union, [set(D.keys()) for D in LD]) 然后 [dic[k] for dic in LD if k in dic] 替换,因此得到的一行代码是:v = {k: [dic[k] for dic in LD if k in dic] for k in reduce(set.union, [set(D.keys()) for D in LD])}

  • 我确实喜欢巧妙/黑客式的单行代码。而且我认为这些是很好的解决方案,非常具有 Python 风格。它们使用了我认为 Python 程序员应该熟悉的核心 Python 习语。

  • 引用 12

    请 - 如果使用像这样的巧妙的单行代码,请添加评论,最好是引用此 SO 答案。你未来的自己会感谢你。

  • 如果你被允许使用外部软件包,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]}
    
  • 这可能是一个版本问题,但上面的代码在 pandas 0.18.1 中返回 {'a': [0, 1], 'b': [2, 3]}。pd.DataFrame(DL).to_dict('records') 按照描述的方式工作。

  • 要从字典列表中查找,很简单:

    您可以使用以下表格:

    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]}]
    

    如果你的问题是基于好奇,那么这就是你的答案。如果你遇到了现实问题,我建议你重新考虑你的数据结构。这两种方法似乎都不是一个非常可扩展的解决方案。

  • 引用 16

    以下是我想到的单行解决方案(为了便于阅读,分散在多行上):

    如果 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]))]
    

    以下是将其转换回列表字典的方法:

    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() }
    
  • 引用 17

    回滚到版本 4 有什么意义?请注意,您在第二个代码片段中设置了错误的范围,并且删除了 Python 代码格式会使代码变得更糟。

  • cytoolz.dicttoolz.merge_with

    文档

    from cytoolz.dicttoolz import merge_with
    
    merge_with(list, *LD)
    
    {'a': [0, 1], 'b': [2, 3]}
    

    非 cython 版本

    文档

    from toolz.dicttoolz import merge_with
    
    merge_with(list, *LD)
    
    {'a': [0, 1], 'b': [2, 3]}
    
  • 感谢@piRSquared 向我介绍了 cytoolz 的世界。它在我的一生中都在哪里?!:)

  • 的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]}
    
返回
作者最近主题: