【发布时间】:2012-04-21 04:54:00
【问题描述】:
有没有可以将元组转换为整数的函数?
例子:
input = (1, 3, 7)
output = 137
【问题讨论】:
-
您的元组是否只有一位整数?你是否计划像
x = (1, 9, 10, 150)这样的处理元组?如果是,你能指定输出应该有什么吗?请提供更多信息。
有没有可以将元组转换为整数的函数?
例子:
input = (1, 3, 7)
output = 137
【问题讨论】:
x = (1, 9, 10, 150) 这样的处理元组?如果是,你能指定输出应该有什么吗?请提供更多信息。
>>> x = (1,3,7)
>>> int(''.join(map(str,x)))
137
【讨论】:
x = (1, 9, 10, 15)的解决方案。目前尚不清楚 OP 是否也想处理它们。
(1, 9, 10, 15) 表示 191015 或 15*1+10*10+9*100+1*1000。根据您处理问题的方式,两者都可以被认为是有效的。他是在考虑输入一组数字还是一组按基数分割的值?
(1, 9, 10, 15) 解释为15*1+10*10+9*100+1*1000。
x = (1, 9, 10, 15) 应该给2015 而不是191015,我想说这完全取决于该元组是如何生成的。无论如何,我asked OP,希望得到一些许可。
只是另一种方法
>>> sum(n*10**i for (i,n) in enumerate(input[::-1]))
137
还有一个
>>> int(str(input).translate(None,'(,) '))
137
【讨论】:
reverse(input) 而不是 input[::-1]。
>>> reduce(lambda rst, d: rst * 10 + d, (1, 2, 3))
123
【讨论】:
reduce() 是 functools.reduce()。
reduce()本质上是一种经典的多项式分解方法,称为Horner's method。
虽然将其转换为字符串然后转换为 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])) 但现在我不会了哈哈
reversed() 是比[::-1] 更好的选择,因为它可以更快并且更易于阅读。
enumerate 和 reversed 有这么长的名字。 ..
这不会将整数转换为字符串并将它们连接起来:
>>> sum([(10 ** i) * input[len(input)-i-1] for i in range(len(input))])
123
这是一行中的for循环。
【讨论】:
怎么样:
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__ 不是一个好主意,尤其是当有其他可用选项时,对吧?
str 永远不会丢失 __contains__ 方法,这避免了 (python) 函数调用和运算符解析开销。
['1', '2', '3'],而不是 '123',并且无论哪种方式,请求的输出都是一个 int,而不是一个字符串。
__add__(),更好的选择是使用functools.partial() 和operator.add() 并使用plus = partial(add, ord("0"))。
@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
自己判断:)
【讨论】:
将元组转换为数字的最简单方法是使用字符串格式化。
input = (1, 3, 7)
output = int('{}{}{}'.format(input[0], input[1], input[2]))
# TEST
print(output) # 137
print(type(output)) # <class 'int'>
【讨论】: