【问题标题】:Cast tuples inside list to int将列表中的元组转换为 int
【发布时间】:2017-06-03 16:36:48
【问题描述】:

如何以如下形式翻转包含元组的列表,

list = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]

放入一个包含整数的列表中,例如,

list = [197, 156, 17, 14, 74, 7]

以最有效的方式?我尝试过递归,但对于大型列表(数千个元组)来说,它的内存太贵了。

【问题讨论】:

    标签: python list int tuples


    【解决方案1】:

    解决问题的一种方法是将子列表中的每个整数转换为字符串,连接并转换为int

    In [1]: l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]
    
    In [2]: [int("".join(map(str, item))) for item in l]
    Out[2]: [197, 156, 17, 14, 74, 7]
    

    或者,使用十的幂(@AChampion 已发布答案的变体):

    In [3]: [sum(10 ** index * value for index, value in enumerate(reversed(item))) 
             for item in l]
    Out[3]: [197, 156, 17, 14, 74, 7]
    

    【讨论】:

    • @AChampion 谢谢,我很确定那里也有一个有效的 numpy 解决方案..
    【解决方案2】:

    将数字列表转换为数字相对简单。将它们转换为字符串join() 并转换回int。或者你可以更数学地做到这一点:

    >>> [sum(n*10**e for e, n in enumerate(reversed(item))) for item in l]
    [197, 156, 17, 14, 74, 7]
    

    注意:不要使用list 作为变量名,因为这会隐藏python list 类型。

    【讨论】:

      【解决方案3】:

      您可以使用functools.reduce 来转换每个元组:

      >>> from functools import reduce
      >>> l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]
      >>> [reduce(lambda x,y: x*10+y, t) for t in l]
      [197, 156, 17, 14, 74, 7]
      

      更新由于问题要求有效的方法,这里是建议答案的测量:

      import itertools as it
      import functools
      
      def conv_reduce(l):
          return [functools.reduce(lambda x,y: x*10+y, t) for t in l]
      
      def conv_str(l):
          return [int("".join(map(str, item))) for item in l]
      
      def conv_pow(l):
          return [sum(n*10**e for n, e in zip(reversed(item), it.count())) for item in l]
      
      def conv_pow2(l):
          return [sum(t[-i-1]*(10**i) for i in range(len(t))) for t in l]
      
      if __name__ == '__main__':
          import timeit
          print('reduce', timeit.timeit("conv_reduce(l)", setup="from __main__ import conv_reduce; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
          print('str', timeit.timeit("conv_str(l)", setup="from __main__ import conv_str; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
          print('pow', timeit.timeit("conv_pow(l)", setup="from __main__ import conv_pow; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
          print('pow2', timeit.timeit("conv_pow2(l)", setup="from __main__ import conv_pow2; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
      

      输出:

      reduce 2.5965667460041004
      str 5.068828338997264
      pow 7.192991987001733
      pow2 8.017168823003885
      

      【讨论】:

      • 如果能加上my function的执行时间就好了。为什么忽略一个:P
      • @MoinuddinQuadri 将您的建议添加为 pow2,我决定最初排除它,因为其他建议之一具有相同的原理,所以我没有假设性能有很大差异。
      【解决方案4】:

      您也可以使用一点数学来实现这一点。在这里,我将元组中的数字与10 的幂以相反的顺序相乘以获得数字。

      >>> my_list = list = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]
      
      #     v sum numbers based on their position at hundred, tens, ones place  
      >>> [sum(t[-i-1]*(10**i) for i in range(len(t))) for t in my_list]
      [197, 156, 17, 14, 74, 7]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-08
        • 2010-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        • 1970-01-01
        • 2021-09-12
        相关资源
        最近更新 更多