【问题标题】:Call int() function on every list element?在每个列表元素上调用 int() 函数?
【发布时间】:2011-03-23 05:24:40
【问题描述】:

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

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?

标签: python list type-conversion integer


【解决方案1】:

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

numbers = [*map(int, numbers)]

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

numbers = map(int, numbers)

【讨论】:

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

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

import numpy as np

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

【讨论】:

    【解决方案3】:

    只是一点,

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

    列表推导更自然,而

    numbers = map(int, numbers)
    

    更快。

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

    有用的阅读:LP vs map

    【讨论】:

    • 不应该是number = map(int, number)吗?
    【解决方案4】:

    在 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, map: 4.9065070152282715
    • @AJJ:map 的设置开销较高,但在参考解释器上,如果转换函数是用 C 实现的 Python 内置函数,则它的每项成本较低。仅对四个值的输入进行测试不会提供有关缩放的有用信息。也就是说,在我自己的测试中(在 Py2.7.12 和 Py3.5.2 上,后者带有 list() 包装),带有 map 的 Py2 甚至在四个元素输入时都赢了,而在 Py3 上只输了一点点;我怀疑您的测试被扭曲以支持 listcomps。
    【解决方案5】:

    这就是list comprehensions 的用途:

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

    【讨论】:

    • 向我显示无效语法
    • 在这个答案被删除之前,还有多少人应该得到无效的语法?
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

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

      sum(int(x) for x in numbers)
      

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

      【讨论】:

        【解决方案8】:

        另一种方式,

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

        【讨论】:

        • 如果您希望只对列表中的某些元素执行操作,这种方式非常有用。这与此线程中的问题无关,但在某些情况下可能会有所帮助
        猜你喜欢
        • 2020-03-18
        • 2016-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多