在每个列表元素上调用int()函数?

215

我有一个包含数字字符串的列表,像这样:

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

我想将每个列表元素转换为整数,使其看起来像这样:

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

我可以使用循环来完成,就像这样:

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

它一定要这么丑吗?我相信有更Pythonic的方法可以用一行代码实现。请帮忙。


1
你使用的是哪个版本的Python? - Mark Byers
8个回答

407

这就是列表推导的用途:

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

6
对我来说显示无效的语法 - Bugs Buggy
在这个答案中,还需要多少人遇到无效语法才能将其删除? - deps_stats

160

在Python 2.x中,另一种方法是使用map函数:

numbers = map(int, numbers)

注意:在 Python 3.x 中,map 返回的是一个 map 对象,如果需要可以将其转换为列表:

numbers = list(map(int, numbers))

12
在Python 3.x中,map返回一个迭代器而不是列表,因此如果需要列表,需要将其写成list(map(int, numbers)) - kennytm
2
我认为目前列表推导式的方法更受青睐。 - extraneon
3
是的...或者考虑使用生成器而不是列表,这取决于您将用它来做什么。使用生成器的好处是,如果您可能不需要查看所有元素,则不必在预先计算它们时浪费时间。 - Mark Byers
上一次我检查的时候,map 对于 int 类型仍然比 LC 稍快,但也许 LC 更容易让人们阅读。 - John La Rooy
4
在Python 2.7.2下使用timeit进行测量:列表推导式的时间为3.578153133392334秒,map函数的时间为4.9065070152282715秒。 - AJJ
1
@AJJ:map的设置开销更高,但在参考解释器上,如果转换函数是在C中实现的Python内置函数,则每个项目的成本较低。对仅包含四个值的输入进行测试将无法提供有关扩展的有用信息。话虽如此,在我自己的测试中(在Py2.7.12和Py3.5.2上,后者使用list()包装),即使对于四个元素的输入,Py2使用map也获胜,并且在Py3上仅略微输掉;我怀疑您的测试对列表推导式有利。 - ShadowRanger

28

只是一个点,

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

列表推导式更自然,但是
numbers = map(int, numbers)

更快。

在大多数情况下,这可能并不重要。

有用的阅读材料:LP vs map


6
不应该是 number = map(int, number) 吗? - Karan

9

如果您打算将这些整数传递给函数或方法,请考虑以下示例:

sum(int(x) for x in numbers)

这种构造方式故意与adamk提到的列表推导式非常相似。去掉方括号后,它被称为生成器表达式,是一种非常节省内存的将参数列表传递给方法的方式。这里有一个很好的讨论:生成器表达式 vs. 列表推导式


8

Python 3中另一种实现方式:

numbers = [*map(int,numbers)]

然而,你可能仅仅需要使用map,因为它返回一个迭代器:

numbers = map(int,numbers)


1
你能解释一下吗?我不熟悉那个语法。谢谢! - abalter
1
我正在使用解包参数列表(https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists) - zhukovgreen
哦,这是 Python 3 的东西。看起来很奇怪,[] 能够接受参数列表。而且,我不知道你可以将迭代器作为参数列表传递。我本来会想到使用 number = list(map(int, numbers))。但还是感谢你的解释! - abalter

3

另一种方式是,

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

4
如果您只想对列表中的某些元素执行操作,那么这种方法非常有用。虽然这与本帖的问题无关,但在某些情况下,它可能会有所帮助。 - Dikla

1

我想整合答案并展示一些timeit结果。

Python 2在这方面表现相当糟糕,但是map比列表推导式略快。

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本身的速度已经提高了4倍以上,但将map生成器对象转换为列表仍然比使用推导式更快,并且通过解包map生成器来创建列表(感谢Artem!)仍然稍微更快一些。
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

注意:在Python 3中,4个元素似乎是交叉点(Python 2中为3),其中推导式略快于解包生成器,但对于具有多个元素的列表,解包生成器仍然比两者都要快。

1
值得一提的是,当创建一个数组时,NumPy也会在此过程中完成这项操作。
import numpy as np

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

array([ 1,  5, 10,  8])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接