【问题标题】:Dictionary to List where the key is repeated the number of times of the value [duplicate]字典列表,其中键重复值的次数[重复]
【发布时间】:2020-11-26 12:57:22
【问题描述】:

我需要将字典转换为列表,其中键重复值的次数。

dict = {'foo':3, 'bar':1}

预期结果:

['foo', 'foo', 'foo', 'bar']

【问题讨论】:

标签: python list dictionary


【解决方案1】:

试试这个:

dict = {'foo':3, 'bar':1}
my_list = []
for key, value in dict.items():
    for _ in range(value):
        my_list.append(key)

输出:

['foo', 'foo', 'foo', 'bar']

【讨论】:

    【解决方案2】:
    if __name__ == '__main__':
        result = []
        dict = {'foo': 3, 'bar': 1}
        for key in dict.keys():
            key_value = dict[key]
            for i in range(key_value):
                result.append(key)
        print(result)
    
    

    或者你可以这样做:

    if __name__ == '__main__':
        result = []
        dict = {'foo': 3, 'bar': 1}
        result = [k for k, v in dict.items() for _ in range(v)]
        print(result)
    

    两个输出都是:

    ['foo', 'foo', 'foo', 'bar']
    

    【讨论】:

      【解决方案3】:

      使用列表推导式创建所需长度的子列表,然后将其展平:

      list(chain.from_iterable([[k] * v for k, v in dict.items()]))
      

      示例

      from itertools import chain
      
      dict = {'foo':3, 'bar':1}
      
      print(list(chain.from_iterable([[k] * v for k, v in dict.items()])))
      # ['foo', 'foo', 'foo', 'bar']
      

      【讨论】:

        【解决方案4】:

        这是一个简单的方法,使用简单的列表理解和列表乘法。

        d = {'foo':3, 'bar':1}
        l = [item for k,v in d.items() for item in [k]*v]
        print(l)
        
        ['foo', 'foo', 'foo', 'bar']
        

        【讨论】:

          【解决方案5】:

          使用collections.Counter

          >>> [*Counter(dict).elements()]
          ['foo', 'foo', 'foo', 'bar']
          

          一个小基准比较这个和一个据说更快的解决方案(和第三种解决方案,做what Counter does,但直接到字典)。数字就是时间,所以低=快:

          0.31 Counter
          0.70 listcomp
          0.27 itertools
          
          0.32 Counter
          0.72 listcomp
          0.28 itertools
          
          0.32 Counter
          0.72 listcomp
          0.29 itertools
          

          基准代码:

          import timeit
          from collections import Counter
          from itertools import chain, starmap, repeat
          
          data = {i: i % 10 + 1 for i in range(1000)}
          
          solutions = {
              'Counter':   lambda: [*Counter(data).elements()],
              'listcomp':  lambda: [v for v, c in data.items() for _ in range(c)],
              'itertools': lambda: list(chain.from_iterable(starmap(repeat, data.items())))
              }
          
          for _ in range(3):
              for name, solution in solutions.items():
                  t = min(timeit.repeat(solution, number=1000))
                  print('%.2f' % t, name)
              print()
          

          【讨论】:

          • @superbrain Holy sh*t,这对我来说没有意义!调用 3 种方法、解包、强制转换到列表比普通列表理解更快吗?怎么会?!时间复杂度应该有点相似,因为嵌套循环的迭代次数与结果中的元素数量相同。
          • @VisioN 我猜这是因为 C 速度与 Python 速度。列表推导为每个元素运行一些 Python。
          • @superbrain 但是列表理解也是用C实现的。也许慢来自范围对象?无论如何,我必须删除我最初的评论,因为它似乎完全错误。好收获!
          • @VisioN 好吧,列表推导“本身”是用 C 实现的。但它一直在评估你的 Python 表达式。
          • [item for k,v in data.items() for item in [k]*v] 不会调用 range(),它会比之前的 listcomp 快 25%。仍然比其他两种解决方案慢。
          【解决方案6】:

          您可以使用简单的列表推导来完成这项工作。

          mylist = [key for key, value in mydict.items() for _ in range(value)]
          

          输出:

          ['foo', 'foo', 'foo', 'bar']
          

          【讨论】:

            猜你喜欢
            • 2019-11-13
            • 2013-09-21
            • 1970-01-01
            • 2021-01-01
            • 2023-03-13
            • 1970-01-01
            • 2019-09-25
            • 1970-01-01
            • 2013-05-22
            相关资源
            最近更新 更多