【问题标题】:Convert dictionary into list with length based on values根据值将字典转换为具有长度的列表
【发布时间】:2017-02-20 14:41:59
【问题描述】:

我有一本字典

d = {1: 3, 5: 6, 10: 2}

我想将它转换为包含字典键的列表。每个键的重复次数应与其关联的值一样多。

我已经编写了完成这项工作的代码:

d = {1: 3, 5: 6, 10: 2}
l = []
for i in d:
    for j in range(d[i]):
        l.append(i)
l.sort()
print(l)

输出:

[1, 1, 1, 5, 5, 5, 5, 5, 5, 10, 10]

但我希望它是一个列表理解。如何做到这一点?

【问题讨论】:

    标签: python list dictionary


    【解决方案1】:

    一种方法是使用itertools.chain 将子列表粘合在一起

    >>> list(itertools.chain(*[[k]*v for k, v in d.items()]))
    [1, 1, 1, 10, 10, 5, 5, 5, 5, 5, 5]
    

    或者,如果您正在处理一个非常大的字典,那么您可以避免使用 itertools.chain.from_iterableitertools.repeat 构建子列表

    >>> list(itertools.chain.from_iterable(itertools.repeat(k, v) for k, v in d.items()))
    [1, 1, 1, 10, 10, 5, 5, 5, 5, 5, 5]
    

    使用使用两个循环的列表推导来比较大型字典的时间:

    >>> d = {i: i for i in range(100)}
    >>> %timeit list(itertools.chain.from_iterable(itertools.repeat(k, v) for k, v in d.items()))
    10000 loops, best of 3: 55.6 µs per loop
    >>> %timeit [k for k, v in d.items() for _ in range(v)]
    10000 loops, best of 3: 119 µs per loop
    

    不清楚您是否要对输出进行排序(您的示例代码不会对其进行排序),但如果是这样,只需预排序 d.items()

    # same as previous examples, but we sort d.items()
    list(itertools.chain(*[[k]*v for k, v in sorted(d.items())]))
    

    【讨论】:

      【解决方案2】:

      [k for k,v in d.items() for _ in range(v)] ...我猜...

      如果你想对它进行排序,你可以这样做

      [k for k,v in sorted(d.items()) for _ in range(v)]

      【讨论】:

        【解决方案3】:

        您可以使用列表推导来做到这一点:

        [i for i in d for j in range(d[i])]
        

        产量:

        [1, 1, 1, 10, 10, 5, 5, 5, 5, 5, 5]
        

        您可以再次对其进行排序以获得您正在寻找的列表。

        【讨论】:

        • 或者您可以在进行列表理解之前对d 进行排序。对于大型字典,这会更快,因为字典的项目比结果列表少。换句话说,[i for i in sorted(d) for j in range(d[i])].
        【解决方案4】:

        Counter.elements() 方法正是这样做的:

        from collections import Counter
        
        d = {1: 3, 5: 6, 10: 2}
        c = Counter(d)
        result = list(c.elements())
        print(result)
        # [1, 1, 1, 5, 5, 5, 5, 5, 5, 10, 10]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-07-25
          • 2018-12-28
          • 2020-01-18
          • 2023-01-13
          • 2019-08-12
          • 2016-03-01
          • 2014-06-23
          相关资源
          最近更新 更多