【问题标题】:Python convert Tuple to IntegerPython将元组转换为整数
【发布时间】:2012-04-21 04:54:00
【问题描述】:

有没有可以将元组转换为整数的函数?

例子:

input = (1, 3, 7)

output = 137

【问题讨论】:

  • 您的元组是否只有一位整数?你是否计划像x = (1, 9, 10, 150) 这样的处理元组?如果是,你能指定输出应该有什么吗?请提供更多信息。

标签: python integer tuples


【解决方案1】:
>>> x = (1,3,7)
>>> int(''.join(map(str,x)))
137

【讨论】:

  • 这个解决方案是迄今为止唯一可以处理x = (1, 9, 10, 15)的解决方案。目前尚不清楚 OP 是否也想处理它们。
  • @RikPoggi 我认为这是一个不太可能的用例,您实际上并不知道这是该案例的正确输出。 OP 从未指定他是否希望 x = (1, 9, 10, 15) 表示 19101515*1+10*10+9*100+1*1000。根据您处理问题的方式,两者都可以被认为是有效的。他是在考虑输入一组数字还是一组按基数分割的值?
  • 嗯是的,尽管他没有将其指定为数字,但我认为我们可以放心地假设它们是。但是,我看不出你怎么能将(1, 9, 10, 15) 解释为15*1+10*10+9*100+1*1000
  • @Lattyware:尚不清楚这是否是一个用例。我非常怀疑x = (1, 9, 10, 15) 应该给2015 而不是191015,我想说这完全取决于该元组是如何生成的。无论如何,我asked OP,希望得到一些许可。
【解决方案2】:

只是另一种方法

>>> sum(n*10**i for (i,n) in enumerate(input[::-1]))
137

还有一个

>>> int(str(input).translate(None,'(,) '))
137

【讨论】:

  • 也许更好:reverse(input) 而不是 input[::-1]
【解决方案3】:
>>> reduce(lambda rst, d: rst * 10 + d, (1, 2, 3))
123

【讨论】:

  • 在 Python 3.x 中值得注意的是,reduce()functools.reduce()
  • 也 +1。我认为这是最易读的,也是最快的(时间上的比较见my answer)。
  • 可以说是最易读的,当然也是最优雅的,但只有在像这个这样的较小情况下是最快的。字符串方法对于大数是最快的。
  • 这里使用reduce()本质上是一种经典的多项式分解方法,称为Horner's method
【解决方案4】:

虽然将其转换为字符串然后转换为 int 是可行的,但这是一种有点 hackish 的方法。我们拥有制作数字所需的所有信息,即:

  • 数字。
  • 数字的位置。

有了这些信息,我们可以通过计算每个位置的每个单元的值,然后乘以该位置的数字来计算数字。然后我们将结果加在一起,我们就有了我们的数字。这可以像这样在一行中完成:

test = (1, 2, 3)
sum((10**pos)*val for pos, val in enumerate(reversed(test)))

让我们分解一下:

>>> list(enumerate(reversed(test)))
[(0, 3), (1, 2), (2, 1)]

那么,如果我们将其相乘:

>>> list((10**pos)*val for pos, val in enumerate(reversed(test)))
[3, 20, 100]

所以我们只需相加得到 123。

编辑:关于速度的说明:

python -m timeit "int(''.join(map(str,(1,2,3))))"
100000 loops, best of 3: 2.7 usec per loop

python -m timeit 'sum((10**pos)*val for pos, val in enumerate(reversed((1,2,3))))'
100000 loops, best of 3: 2.29 usec per loop

python -m timeit -s 'from functools import reduce' 'reduce(lambda rst, d: rst * 10 + d, (1, 2, 3))'
1000000 loops, best of 3: 0.598 usec per loop

因此,如果您想提高速度,Andrey Yazu's answer 可以。我对我觉得更具可读性的东西感到很痛苦。我总是觉得 lambdas 很丑,但总的来说,我认为它仍然是更易读的方法。

编辑 2:使用非常大的元组:

长度 20:

python -m timeit -s "x=tuple(list(range(1,10))*2)" "int(''.join(map(str, x)))"
100000 loops, best of 3: 5.45 usec per loop

python -m timeit -s "x=tuple(list(range(1,10))*2)" "sum((10**pos)*val for pos, val in enumerate(reversed(x)))" 
100000 loops, best of 3: 11.7 usec per loop

python -m timeit -s "x=tuple(list(range(1,10))*2)" -s 'from functools import reduce' 'reduce(lambda rst, d: rst * 10 + d, x)'
100000 loops, best of 3: 4.18 usec per loop

长度 100:

python -m timeit -s "x=tuple(list(range(1,10))*10)" "int(''.join(map(str, x)))"
100000 loops, best of 3: 18.6 usec per loop

python -m timeit -s "x=tuple(list(range(1,10))*10)" "sum((10**pos)*val for pos, val in enumerate(reversed(x)))"
10000 loops, best of 3: 72.9 usec per loop

python -m timeit -s "x=tuple(list(range(1,10))*10)" -s 'from functools import reduce' 'reduce(lambda rst, d: rst * 10 + d, x)'
10000 loops, best of 3: 25.6 usec per loop

在这里我们看到最快的方法实际上是字符串操作 - 然而,现实情况是你不太可能在例如 10 位数字范围之外使用它 - 其中reduce() 方法仍然占主导地位 -明智的。我还认为 string 方法很老套,对读者来说不太清楚,这通常是优先于速度的。

【讨论】:

  • 我刚要发sum(10**i*x for i,x in enumerate(x[::-1])) 但现在我不会了哈哈
  • 这个答案和我的不一样吗?
  • @Abhijit 有趣的是这些事情的进展。我不确定我是否先在这里发布,但我的答案有很多解释,使用reversed() 是比[::-1] 更好的选择,因为它可以更快并且更易于阅读。
  • 是的,我知道,只是想要一个更简短的答案,我想我会坚持正确地做事,即使它会产生更长的代码,特别是因为 enumeratereversed 有这么长的名字。 ..
  • @jamylak 使用 Python,该语言的很大一部分目标是可读性和可维护性,所以我总是建议更多地为可读性而不是简短的工作,但每个人都有自己的。跨度>
【解决方案5】:

这不会将整数转换为字符串并将它们连接起来:

>>> sum([(10 ** i) * input[len(input)-i-1] for i in range(len(input))])
123

这是一行中的for循环。

【讨论】:

    【解决方案6】:

    怎么样:

    In [19]: filter(set('0123456789').__contains__,str((1,2,3)))
    Out[19]: '123'
    

    我相信这是最简单的解决方案。

    一个非常快速的解决方案是:

    plus=ord("0").__add__ # separate out for readability; bound functions are partially-applied functions
    int(str(bytearray(map(plus,x)))) #str is necessary
    

    这如何与次快的解决方案相提并论:

    $ python -m timeit -s 'x=tuple(list(range(1,10))*10)' 'plus=ord("0").__add__;int(str(bytearray(map(plus,x))))'
    10000 loops, best of 3: 47.7 usec per loop
    
    $ python -m timeit -s "x=tuple(list(range(1,10))*10)" "int(''.join(map(str, x)))"
    10000 loops, best of 3: 59 usec per loop
    

    【讨论】:

    • 使用__functions__ 不是一个好主意,尤其是当有其他可用选项时,对吧?
    • @0xc0de 为什么不呢? str 永远不会丢失 __contains__ 方法,这避免了 (python) 函数调用和运算符解析开销。
    • 请注意,在 Python 3.x 中,您的第一个示例返回 ['1', '2', '3'],而不是 '123',并且无论哪种方式,请求的输出都是一个 int,而不是一个字符串。
    • 关于引用__add__(),更好的选择是使用functools.partial()operator.add() 并使用plus = partial(add, ord("0"))
    • @Lattyware 在可能的情况下使用部分更好吗?至于第一个示例的行为,我想您可以弄清楚如何将其更改为 int;而 Python 3 只是对该语言进行了一些奇怪的更改。
    【解决方案7】:

    @Marcinbytearray 解决方案确实是 Python 2 中最快的解决方案。

    按照 Python 3 中的同一行,您可以这样做:

    >>> plus = ord("0").__add__
    >>> int(bytes(map(plus, x)))
    

    Python 3 处理字符串和字节的方式与 Python 2 不同,所以为了更好地理解这种情况,我做了一些计时。以下是我在我的机器上得到的结果。

    使用 Python 2.7 (code):

    int(str(bytearray(map(plus, x))))           8.40 usec/pass
    int(bytearray(map(plus, x)).decode())       9.85 usec/pass
    int(''.join(map(str, x)))                   11.97 usec/pass
    reduce(lambda rst, d: rst * 10 + d, x)      22.34 usec/pass
    

    使用 Python 3.2 (code):

    int(bytes(map(plus, x)))                    7.10 usec/pass
    int(bytes(map(plus, x)).decode())           7.80 usec/pass
    int(bytearray(map(plus,x)).decode())        7.99 usec/pass
    int(''.join(map(str, x)))                   17.46 usec/pass
    reduce(lambda rst, d: rst * 10 + d, x)      19.03 usec/pass
    

    自己判断:)

    【讨论】:

      【解决方案8】:

      将元组转换为数字的最简单方法是使用字符串格式化。

      input = (1, 3, 7)
      output = int('{}{}{}'.format(input[0], input[1], input[2]))
      
      # TEST
      print(output) # 137
      print(type(output)) # <class 'int'>
      

      【讨论】:

        猜你喜欢
        • 2021-11-23
        • 2012-10-09
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 2016-01-25
        • 2019-12-04
        • 2012-08-28
        • 2016-04-22
        相关资源
        最近更新 更多