Chamar a função int () em todos os elementos da lista?


184

Eu tenho uma lista com seqüências numéricas, assim:

numbers = ['1', '5', '10', '8'];

Gostaria de converter todos os elementos da lista em números inteiros, assim ficaria assim:

numbers = [1, 5, 10, 8];

Eu poderia fazer isso usando um loop, assim:

new_numbers = [];
for n in numbers:
    new_numbers.append(int(n));
numbers = new_numbers;

Tem que ser tão feio? Tenho certeza de que há uma maneira mais pitônica de fazer isso em uma linha de código. Por favor, me ajude.


1
Qual versão do Python você está usando?
Mark Byers

Respostas:



131

No Python 2.x, outra abordagem é usar map:

numbers = map(int, numbers)

Nota: no Python 3.x mapretorna um objeto de mapa que você pode converter em uma lista, se desejar:

numbers = list(map(int, numbers))

11
No Python 3.x, mapretorna um iterador em vez de uma lista, portanto, ele precisa ser escrito como list(map(int, numbers))se fosse necessária uma lista.
Kennytm

2
Acho que atualmente a abordagem de compreensão da lista é um pouco mais favorecida.
Extraneon

3
@extraneon: Sim ... ou talvez considere usar um gerador em vez de uma lista, dependendo do que você usará. A vantagem de um gerador é que, se você não precisar examinar todos os elementos, não precisará perder tempo calculando-os com antecedência.
Mark Byers

4
Medido com timeit sob Python 2.7.2: LC: 3,578153133392334, mapa: 4,9065070152282715
AJJ

1
@AJJ: mappossui uma sobrecarga de configuração mais alta, mas no interpretador de referência, se a função de transformação for uma função interna do Python implementada em C, ela terá um custo menor por item. Testar em uma entrada de apenas quatro valores não fornecerá informações úteis sobre dimensionamento. Dito isto, em meus próprios testes (no Py2.7.12 e Py3.5.2, o último com list()quebra automática), o Py2 mapvenceu até por quatro entradas de elementos e perde apenas uma pequena margem no Py3; Eu suspeito que seus testes foram distorcidos em favor dos listcomps.
ShadowRanger 8/16

21

apenas um ponto

numbers = [int(x) for x in numbers]

a compreensão da lista é mais natural, enquanto

numbers = map(int, numbers)

é mais rápido.

Provavelmente isso não importa na maioria dos casos

Leitura útil: LP vs map


6
Não deveria ser number = map (int, number)?
Karan

9

Se você pretende passar esses números inteiros para uma função ou método, considere este exemplo:

sum(int(x) for x in numbers)

Essa construção é intencionalmente notavelmente semelhante às compreensões de lista mencionadas por adamk. Sem os colchetes, isso é chamado de expressão geradora e é uma maneira muito eficiente em termos de memória de passar uma lista de argumentos para um método. Uma boa discussão está disponível aqui: Expressões do Gerador vs. Compreensão da Lista


4

Outra maneira de fazê-lo no Python 3:

numbers = [*map(int, numbers)]


1
Você pode explicar isso? Não estou familiarizado com essa sintaxe. Obrigado!
abalter

1
Estou usando a lista de argumentos de descompactação ( docs.python.org/3/tutorial/… )
zhukovgreen

Aha, uma coisa de python 3. Parece estranho ter []uma lista de argumentos. E eu não sabia que você poderia passar um iterador como uma lista de argumentos. Eu teria pensado em fazer number = list(map(int, numbers)). Mas obrigado pela explicação!
abalter

3

De outra maneira

for i, v in enumerate(numbers): numbers[i] = int(v)

6
OP disse pythônico
SilentGhost

3
Dessa forma, é muito útil se você deseja executar a operação apenas em alguns dos elementos da lista. Esta não é relevante para a questão neste segmento, mas pode haver casos em que é útil
Dikla

1

Pensei em consolidar as respostas e mostrar alguns timeitresultados.

O Python 2 é péssimo nisso, mas mapé um pouco mais rápido que a compreensão.

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
116.25092001434314
>>> timeit.timeit('map(int, l)', setup)
106.66044823117454

O Python 3 é 4x mais rápido por si só, mas converter o mapobjeto gerador em uma lista ainda é mais rápido que a compreensão, e criar a lista descompactando o mapgerador (obrigado Artem!) É um pouco mais rápido ainda.

Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
25.133059591551955
>>> timeit.timeit('list(map(int, l))', setup)
19.705547827217515
>>> timeit.timeit('[*map(int, l)]', setup)
19.45838406513076

Nota: No Python 3, 4 elementos parecem ser o ponto de cruzamento (3 no Python 2), onde a compreensão é um pouco mais rápida, embora a descompactação do gerador seja ainda mais rápida do que nas listas com mais de 1 elemento.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.