web-dev-qa-db-fra.com

Comment convertir une liste de plusieurs entiers en un seul entier?

Comment convertir une liste dans Python 3.5 telle que:

x=[1, 3, 5]

à un int de 135 (un entier entier)?

14
chess_predictor

Si vous avez une liste de ints et que vous souhaitez les associer, vous pouvez utiliser map avec str pour les convertir en chaînes, join sur la chaîne vide, puis relancer ints avec int .

En code, cela ressemble à ceci:

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

et r a maintenant la valeur souhaitée de 135.

Ceci, bien sûr, est une approche limitée qui vient avec certaines conditions. Pour que la liste en question ne contienne rien d’autre que ints positif (en tant qu’échantillon) ou des chaînes représentant des ints, sinon les étapes de conversion en chaîne risquent d’échouer ou la jonction de nombres (négatifs) sera compliquée. 

27

Voici une méthode plus mathématique qui ne nécessite pas de conversion en chaîne. Notez que cela ne fonctionnera que si 0 <= i <= 9.

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

L'idée est de multiplier chaque élément de la liste par sa puissance correspondante de 10, puis d'additionner le résultat.

30
brianpck

En utilisant uniquement les mathématiques (pas de conversions vers ou depuis des chaînes), vous pouvez utiliser la fonction reduce (functools.reduce en Python 3)

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

Ceci utilise la règle de Horner, qui factorise le polynôme représentant le nombre afin de réduire le nombre de multiplications. Par exemple,

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

En conséquence, cela est plus rapide que la puissance de calcul de 10 ou la création d'une chaîne et la conversion du résultat en entier.

>>> 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

Pour être juste, la conversion de chaîne est plus rapide une fois que le nombre de chiffres est plus grand.

>>> 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
23
chepner

Si vous n'aimez pas la carte, vous pouvez toujours utiliser une liste de compréhension:

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