Comment convertir une liste dans Python 3.5 telle que:
x=[1, 3, 5]
à un int de 135
(un entier entier)?
Si vous avez une liste de int
s 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 int
s 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 int
s positif (en tant qu’échantillon) ou des chaînes représentant des int
s, sinon les étapes de conversion en chaîne risquent d’échouer ou la jonction de nombres (négatifs) sera compliquée.
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.
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
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))