【问题标题】:pythonic way of splitting a list of lists into a length-keyed dictionary?pythonic将列表列表拆分为长度键控字典的方法?
【发布时间】:2017-05-12 08:06:52
【问题描述】:
xs = [
        [1,2,3,4],
        [5,6,7,8],
        [9,0,0,1],
        [2,3],
        [0],
        [5,8,3,2,5,1],
        [6,4],
        [1,6,9,9,2,9]
]

""" expected output:

    xs_dict = {
        1: [[0]]
        2: [[2,3],[6,4]]
        4: [[1,2,3,4],[5,6,7,8],[9,0,0,1]]
        6: [[5,8,3,2,5,1],[1,6,9,9,2,9]]
    }
"""

我可以这样做,例如,通过

xs_dict = {}
for x in xs:
    aux = xs_dict.get(len(x),[])
    aux.append(x)
    xs_dict[len(x)] = aux

print(xs_dict)

但我不禁觉得应该有一个更蟒蛇的方式来实现这一点。

这是什么?

【问题讨论】:

    标签: python list python-3.x dictionary


    【解决方案1】:
    from itertools import groupby
    
    xs_dict = {
        key: list(value)
        for (key, value) in groupby(sorted(xs, key=len), len)
    }
    

    正如下面的 cmets 中所讨论的,对输入进行必要的排序是一个不必要的昂贵步骤。对于大输入,这将大大减慢该算法的速度。然后考虑使用@hiroprotagonist 的解决方案,或者将groupby(sorted(…), …) 替换为可以处理未排序输入的groupby()

    【讨论】:

    • 是的,实际上我发现groupby() 需要排序输入是一个。一般来说,排序是不必要的昂贵。至少应该有一个不是这样工作但积极收集的版本。
    • 该死!那很好! +1
    • @hiroprotagonist 这不是比你的解决方案效率低吗?
    • 是的,我认为我们同意,但groupbyOfUnsorted() 基本上是defaultdict 解决方案,或者您会以其他方式实现它吗? @hiroprotagonist
    • 我们都同意这是多么难得的款待,多么文明,无论如何都要感谢
    【解决方案2】:

    你可以使用defaultdict:

    from collections import defaultdict
    
    xs_dict = defaultdict(list)
    for item in xs:
        xs_dict[len(item)].append(item)
    

    python dicts 还有一个很好的方法叫做setdefault(这样你就不需要导入任何东西):

    xs_dict = {}
    for item in xs:
        xs_dict.setdefault(len(item), []).append(item)
    

    【讨论】:

      【解决方案3】:

      1 班轮:

      res = {len(s): [d for d in xs if len(d) == len(s)] for s in xs}
      

      【讨论】:

      • 这做了几件事两次。
      • 从来没有说过它是有效的:P
      • @afifit 你也从来没有说过这不是 xD。它的扩展性很差
      • 我想您可以通过将xs 更改为一组长度来优化它,但仍然不完美
      【解决方案4】:
      import pprint
      from collections import defaultdict
      from itertools import groupby
      
      xs = [
          [1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 0, 0, 1],
          [2, 3],
          [0],
          [5, 8, 3, 2, 5, 1],
          [6, 4],
          [1, 6, 9, 9, 2, 9]
      ]
      
      data = defaultdict(list)
      
      for result, group in groupby(sorted(xs, key=len), len):
          for item in group:
              data[result].append(item)
      
      pprint.pprint(dict(data))
      

      给我

      {1: [[0]],
       2: [[2, 3], [6, 4]],
       4: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 0, 1]],
       6: [[5, 8, 3, 2, 5, 1], [1, 6, 9, 9, 2, 9]]}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-19
        • 1970-01-01
        • 2020-10-01
        • 2011-05-04
        • 1970-01-01
        • 1970-01-01
        • 2017-04-25
        • 2020-04-23
        相关资源
        最近更新 更多