ChatGPT解决这个技术问题 Extra ChatGPT

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

我有一个带有数字字符串的列表,如下所示:

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 的方式可以在一行代码中做到这一点。请帮帮我。

你使用的是什么版本的 Python?

A
Aran-Fey

这就是 list comprehensions 的用途:

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

向我显示无效语法
在这个答案被删除之前,还有多少人应该在这个答案中得到无效的语法?
A
Aran-Fey

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

numbers = map(int, numbers)

注意:在 Python 3.x map 中返回一个地图对象,您可以根据需要将其转换为列表:

numbers = list(map(int, numbers))

在 Python 3.x 中,map 返回迭代器而不是列表,因此如果需要列表,则需要将其写为 list(map(int, numbers))
我认为目前列表理解方法更受青睐。
@extraneon:是的......或者也许考虑使用生成器而不是列表,这取决于您将使用它的目的。生成器的优点是,如果您可能不需要查看所有元素,那么您不必浪费时间提前计算它们。
在 Python 2.7.2 下使用 timeit 测量:LC:3.578153133392334,地图:4.9065070152282715
@AJJ:map 具有较高的设置开销,但在参考解释器上,如果转换函数是用 C 实现的 Python 内置函数,则它的每项成本较低。仅对四个值的输入进行测试不会提供有关缩放的有用信息。也就是说,在我自己的测试中(在 Py2.7.12 和 Py3.5.2 上,后者带有 list() 包装),带有 map 的 Py2 甚至在四个元素输入时都赢了,而在 Py3 上只输了一点点;我怀疑您的测试被扭曲以支持 listcomps。
A
Aran-Fey

只是一点,

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

列表理解更自然,而

numbers = map(int, numbers)

是比较快的。

在大多数情况下,这可能无关紧要

有用的阅读:LP vs map


不应该是 number = map(int, number) 吗?
R
Ry-

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

sum(int(x) for x in numbers)

这种结构故意与 adamk 提到的列表推导非常相似。没有方括号,它被称为生成器表达式,是一种将参数列表传递给方法的非常节省内存的方法。此处提供了很好的讨论:Generator Expressions vs. List Comprehension


z
zhukovgreen

在 Python 3 中实现它的另一种方法:

numbers = [*map(int, numbers)]

然而,理想情况下,您可能会对 map 感到满意,因为它返回了一个迭代器:

numbers = map(int, numbers)


你能解释一下吗?我不熟悉那种语法。谢谢!
我正在使用解包参数列表 (docs.python.org/3/tutorial/…)
啊哈,python 3 的东西。让 [] 采用参数列表似乎很奇怪。而且,我不知道您可以将迭代器作为参数列表传递。我本来想做number = list(map(int, numbers))。但是感谢您的解释!
N
Nick Dandoulakis

另一种方式,

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

如果您希望仅对列表中的某些元素执行操作,这种方式非常有用。这与此线程中的问题无关,但在某些情况下可能会有所帮助
J
Jim

以为我会合并答案并显示一些 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 个元素的列表更快。


A
Arne

还可能值得注意的是,NumPy 在创建数组时会即时执行此操作:

import numpy as np

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