Python конвертирует Tuple в Integer

Есть ли какая-либо функция, которая может преобразовать кортеж в целое число?

Пример:

input = (1, 3, 7)

output = 137

Ответ 1

>>> reduce(lambda rst, d: rst * 10 + d, (1, 2, 3))
123

Ответ 2

>>> x = (1,3,7)
>>> int(''.join(map(str,x)))
137

Ответ 3

При преобразовании его в строку, а затем в int работает, это несколько хакерский метод. У нас есть вся необходимая информация, чтобы сделать число, а именно:

  • Цифры.
  • Позиция цифр.

Поскольку у нас есть эта информация, мы можем вычислить число, вычислив значение каждой единицы в каждой позиции, затем умножая ее на цифру в указанном положении. Затем мы объединяем результаты, и у нас есть наш номер. Это можно сделать в одной строке следующим образом:

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 имеет его. Я разорван на то, что, по моему мнению, более удобочитаемо. Я всегда нахожу лямбды уродливыми как-то, но в целом, я думаю, что это еще более читаемый метод.

Изменить 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

Здесь мы видим, что самый быстрый метод на самом деле является строковой операцией, однако реальность заключается в том, что вы вряд ли будете использовать это вне диапазона, например, десятизначных чисел, где метод reduce() все еще доминирует в скорости - мудрый. Я также хотел бы утверждать, что строковый метод хакерский и менее понятный для читателя, который обычно является приоритетом по скорости.

Ответ 4

это не преобразует целые числа в строки и не конкатцирует их:

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

это цикл for в одной строке.

Ответ 5

Как насчет:

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

Ответ 6

@Marcin bytearray решение действительно самое быстрое в 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

Судите сами:)

Ответ 7

Самый простой способ изменить кортеж в число - использовать форматирование строк.

input = (1, 3, 7)
output = int('{}{}{}'.format(input[0], input[1], input[2]))

# TEST
print(output) # 137
print(type(output)) # <class 'int'>

Ответ 8

Еще один способ сделать это

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

и еще один

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