ChatGPT解决这个技术问题 Extra ChatGPT

Call int() function on every list element?

I have a list with numeric strings, like so:

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

I would like to convert every list element to integer, so it would look like this:

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

I could do it using a loop, like so:

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

Does it have to be so ugly? I'm sure there is a more pythonic way to do this in a one line of code. Please help me out.

What version of Python are you using?

A
Aran-Fey

This is what list comprehensions are for:

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

Shows invalid syntax to me
How many more people should get invalid syntax in this answer before it's removed?
A
Aran-Fey

In Python 2.x another approach is to use map:

numbers = map(int, numbers)

Note: in Python 3.x map returns a map object which you can convert to a list if you want:

numbers = list(map(int, numbers))

In Python 3.x, map returns an iterator instead of a list, so it needs to be written as list(map(int, numbers)) if a list is needed.
I think currently the list comprehension approach is a bit more favored.
@extraneon: Yeah... or perhaps consider using a generator instead of a list, depending on what you will use it for. The advantage of a generator is that if you might not need to look at all elements then you won't have to waste time calculating them in advance.
Measured with timeit under Python 2.7.2: LC: 3.578153133392334, map: 4.9065070152282715
@AJJ: map has higher setup overhead, but on the reference interpreter, if the transform function is a Python built-in function implemented in C, it has a lower per item cost. Testing on an input of only four values will not provide useful information on scaling. That said, in my own tests (on Py2.7.12 and Py3.5.2, the latter with list() wrapping), Py2 with map won even for four element inputs, and loses by only a tiny margin on Py3; I suspect your tests were warped in favor of listcomps.
A
Aran-Fey

just a point,

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

the list comprehension is more natural, while

numbers = map(int, numbers)

is faster.

Probably this will not matter in most cases

Useful read: LP vs map


Shouldn't it be number = map(int, number)?
R
Ry-

If you are intending on passing those integers to a function or method, consider this example:

sum(int(x) for x in numbers)

This construction is intentionally remarkably similar to list comprehensions mentioned by adamk. Without the square brackets, it's called a generator expression, and is a very memory-efficient way of passing a list of arguments to a method. A good discussion is available here: Generator Expressions vs. List Comprehension


z
zhukovgreen

Another way to make it in Python 3:

numbers = [*map(int, numbers)]

However ideally you may be happy just with map, as it is returning an iterator:

numbers = map(int, numbers)


Can you explain this? I'm not familiar with that syntax. Thanks!
I am using unpacking arguments list (docs.python.org/3/tutorial/…)
Aha, a python 3 thing. Seems strange to have [] take an argument list. And, I didn't know you could pass an iterator as an argument list. I would have thought to do number = list(map(int, numbers)). But thanks for the explanation!
N
Nick Dandoulakis

Another way,

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

This way is very useful if you wish to execute the operation only on some of the elements in the list. This isn't relevant for the question in this thread but there can be cases when it's helpful
J
Jim

Thought I'd consolidate the answers and show some timeit results.

Python 2 sucks pretty bad at this, but map is a bit faster than comprehension.

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

Python 3 is over 4x faster by itself, but converting the map generator object to a list is still faster than comprehension, and creating the list by unpacking the map generator (thanks Artem!) is slightly faster still.

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

Note: In Python 3, 4 elements seems to be the crossover point (3 in Python 2) where comprehension is slightly faster, though unpacking the generator is still faster than either for lists with more than 1 element.


A
Arne

It may also be worth noting that NumPy will do this on the fly when creating an array:

import numpy as np

numbers = ['1', '5', '10', '8']
numbers = np.array(numbers,
                   dtype=int)
numbers
array([ 1,  5, 10,  8])