2016-12-09 5 views
13

Как преобразовать список в Python 3.5, такие как:Как преобразовать список целых чисел в одно целое?

x=[1, 3, 5] 

к междунар из 135 (целое число),?

+2

Названные просто говорит «целый» для элементов списка. Какое значение должно быть возвращено, скажем, '[-3,14,0, -163]',? –

+0

Вывод: неверный литерал для int() с базой 10 –

+1

Но в вашем описании ничего не сказано о том, что этот список недействителен, ни о литералах (элементы списка не могут быть переменными?), Ни о базе 10. (И он говорит, что вывод должен быть единственное целое число, а не «недопустимый литерал».) –

ответ

26

Если у вас есть список int с, и вы хотите присоединиться к ним вместе, вы можете использовать map с str, чтобы преобразовать их в строки, join их на пустую строку, а затем бросили обратно в int с с int.

В коде это выглядит следующим образом:

r = int("".join(map(str, x))) 

и r теперь имеет желаемое значение 135.

Это, конечно, ограниченный подход, который приходит с некоторыми условиями. Он требует, чтобы указанный список не содержал ничего, кроме положительного int s (как ваш образец) или строки, представляющие int s, иначе шаги преобразования в строку могут завершиться неудачей или объединение (отрицательных) чисел будет неудобным.

+0

Это медленнее, чем вычисление значения численно, но имеет преимущество работы для баз больше 10. – chepner

+0

@chepner будет быстрее с большими номерами, и ваша версия, как правило, быстрее с меньшим числом (30 цифр и меньше на моем компьютере). –

+0

Стоит отметить, что эта версия не сработает, если первое целое число равно 0. – asmeurer

30

Вот более математический способ, который не должен преобразовывать назад и вперед в строку. Обратите внимание, что он будет работать только тогда, когда 0 = < я < = 9.

>>> x = [1, 3, 5] 
>>> sum(d * 10**i for i, d in enumerate(x[::-1])) 
135 

Идея состоит в том, чтобы умножить каждый элемент в списке его соответствующей мощности 10, а затем суммировать результат.

+2

Если вы хотите, чтобы он был эффективным, было бы лучше сделать 'reverse (x)', а не 'x [:: - 1]'? Последний должен создать совершенно новый список, но первый - просто генератор. – Justin

22

Используя только математику (без преобразования в или из строк), вы можете использовать функцию reduce (functools.reduce в Python 3)

b = reduce(lambda total, d: 10*total + d, x, 0) 

Это делает использование правила Хорнера, какие факторы полинома, представляющее число к уменьшите количество умножений. Например,

1357 = 1*10*10*10 + 3*10*10 + 5*10 + 7  # 6 multiplications 
    = ((1*10 + 3)*10 + 5)*10 + 7   # 3 multiplications 

В результате этого происходит быстрее, чем вычисления силы 10 или создание строки и преобразование результата в целое число.

>>> timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', 'from functools import reduce; x=[1,3,5,7]') 
0.7217515400843695 
>>> timeit.timeit('int("".join(map(str, [1,3,5,7])))') 
1.425914661027491 
>>> timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', 'x=[1,3,5,7]') 
1.897974518011324 

Честно говоря, преобразование строки быстрее, когда число цифр становится больше.

>>> import timeit 

# 30 digits 
>>> setup='from functools import reduce; x=[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
6.520374411018565 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
6.797425839002244 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
19.430233853985555 

# 60 digits 
>>> setup='from functools import reduce; x=2*[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
13.648188541992567 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
12.864593736943789 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
44.141602706047706 

# 120 digits! 
>>> setup='from functools import reduce; x=4*[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
28.364255172084086 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
25.184791765059344 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
99.88558598596137 
+0

Это не сработает с [1, 0, 'e', ​​3]! –

+1

@ LoïcFaure-Lacroix OP специально задает вопрос о массиве целых чисел – brianpck

+0

@brianpck Да, я знаю, но generic иногда лучше, чем нет. Кстати, тесты timeit - хороший способ проверить вещи. Что ответ не говорит о том, что метод уменьшения будет хуже с большими числами. Это хорошо с меньшими номерами, но как только он будет получать номера с длиной около 30 номеров, версия str будет самым быстрым решением. –

1

Если вам не нравится карта, которую вы всегда можете использовать список понимание:

s = [str(i) for i in x] 
r = int("".join(s)) 
+0

... и если вам нравятся списки, вы всегда можете использовать выражение генератора и избегать одного из циклов: 'int (" ". Join (str (i) для i в x))' – Kroltan