【问题标题】:How to create an integer array in Python?如何在 Python 中创建一个整数数组?
【发布时间】:2010-12-24 00:15:14
【问题描述】:

应该没那么难。我的意思是在 C 中,

int a[10]; 

就是你所需要的。如何为随机大小创建一个全零数组。我知道 NumPy 中的 zeros() 函数,但必须有一个简单的内置方法,而不是另一个模块。

【问题讨论】:

  • Python 没有内置的数组数据结构。最接近的就是列表。
  • 令人惊讶的是,实际上没有人问你需要这个做什么。通常列表很好,不管您可以在其中存储其他东西(它们只是对其他对象的引用列表,可以是任何东西)。但也许有一些原因对你不起作用......
  • 我强烈推荐 Python 教程:docs.python.org/tutorial 它只需要你几个小时的时间。

标签: python arrays


【解决方案1】:
>>> a = [0] * 10
>>> a
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

【讨论】:

    【解决方案2】:
    a = 10 * [0]
    

    给你一个长度为 10 的数组,用零填充。

    【讨论】:

    • 这在Python中不叫数组,它是一个列表
    • 我相信提问者从 C 中获取了“数组”术语,并在 Python 中寻找一个紧密的内置替代方案。在很多情况下,只需要在 Python 中使用一个列表。
    • catchmeifyoutry:无论 C 替代方案是什么,我仍然会让提问者知道他们使用的正确术语
    • 提问者知道其中的区别。这就是他坚持使用“数组”的原因。感谢您匿名谈论我。 :-)
    【解决方案3】:

    两种方式:

    x = [0] * 10
    x = [0 for i in xrange(10)]
    

    编辑:将range 替换为xrange 以避免创建另一个列表。

    另外:正如包括 Pi 和 Ben James 在内的许多其他人所指出的,这会创建一个 list,而不是 Python 数组。虽然列表在许多情况下足够且容易,但对于性能关键用途(例如,当在数千个对象中重复时),您可以查看 python 数组。查找 array 模块,如本帖其他答案中所述。

    【讨论】:

    • 这是一个列表。它可以包含任何类型的对象,而不仅仅是整数。而且它使用的 RAM 比整数所需的要多得多。
    • 不仅如此,range 还返回一个列表。所以第二行至少会使用两倍于结果列表的内存。
    • 列表相乘时要小心——它会给你带来可变对象的麻烦。乘法不会克隆项目,而只是为您提供在列表中多次出现的相同对象。试试这个:a = [[1]]*3; a[1].append(2)。因此,附加到a[1] 将真正改变a 的所有项目并给你[[1,2],[1,2],[1,2]]
    • 并在 py3k 中将 xrange 替换回 range
    • +1。可以设计一些不适用的极端情况,但您的答案是该问题的自然、pythonic 解决方案。
    【解决方案4】:

    如果您对列表不满意(因为它们可以包含任何内容并占用太多内存),您可以使用高效的整数数组:

    import array
    array.array('i')
    

    here

    如果需要初始化,

    a = array.array('i',(0 for i in range(0,10)))
    

    【讨论】:

    • 这将初始化一个包含 9 个元素的数组,而不是 10 个
    • 这似乎是最有效的方式。
    • 对不起,我也试过了。虽然这是最合理的方式,但对于需要“列表”的初始化部分,它会变得很奇怪。
    • 它是一个生成器表达式,因此对于非常大的数组来说它不会占用内存,但我同意它与memset 相比效率低下。
    • 这是 Python ffs,memset 和 C 级效率都不是问题。
    【解决方案5】:

    使用 array 模块。有了它,您可以高效地存储相同类型的集合。

    >>> import array
    >>> import itertools
    >>> a = array_of_signed_ints = array.array("i", itertools.repeat(0, 10))
    

    更多信息 - 例如不同类型,看the documentation of the array module。对于多达 100 万个条目,这应该会让人感觉非常快。对于 1000 万个条目,我的本地机器思考 1.5 秒。

    array.array 的第二个参数是一个generator,它在读取时构造定义的序列。这样,数组模块可以一个一个地消耗零,但生成器只使用常量内存。如果序列变长,这个生成器不会变大(内存方面)。数组当然会增长,但这应该很明显。

    您可以像使用列表一样使用它:

    >>> a.append(1)
    >>> a.extend([1, 2, 3])
    >>> a[-4:]
    array('i', [1, 1, 2, 3])
    >>> len(a)
    14
    

    ...或者简单地将其转换为列表:

    >>> l = list(a)
    >>> len(l)
    14
    

    令人惊讶

    >>> a = [0] * 10000000
    

    构造速度比数组方法快。去搞清楚! :)

    【讨论】:

      【解决方案6】:
      import random
      
      def random_zeroes(max_size):
        "Create a list of zeros for a random size (up to max_size)."
        a = []
        for i in xrange(random.randrange(max_size)):
          a += [0]
      

      如果您使用的是 Python 3.x,请改用 range

      【讨论】:

        【解决方案7】:

        如果您需要快速初始化一个数组,您可以通过块而不是使用生成器初始化器来完成它,它会更快。通过[0]*count 创建列表同样快。

        import array
        
        def zerofill(arr, count):
            count *= arr.itemsize
            blocksize = 1024
            blocks, rest = divmod(count, blocksize)
            for _ in xrange(blocks):
                arr.fromstring("\x00"*blocksize)
            arr.fromstring("\x00"*rest)
        
        def test_zerofill(count):
            iarr = array.array('i')
            zerofill(iarr, count)
            assert len(iarr) == count
        
        def test_generator(count):
            iarr = array.array('i', (0 for _ in xrange(count)))
            assert len(iarr) == count
        
        def test_list(count):
            L = [0]*count
            assert len(L) == count
        
        if __name__ == '__main__':
            import timeit
            c = 100000
            n = 10
            print timeit.Timer("test(c)", "from __main__ import c, test_zerofill as test").repeat(number=n)
            print timeit.Timer("test(c)", "from __main__ import c, test_generator as test").repeat(number=n)
            print timeit.Timer("test(c)", "from __main__ import c, test_list as test").repeat(number=n)
        

        结果:

        (array in blocks) [0.022809982299804688, 0.014942169189453125, 0.014089107513427734]
        (array with generator) [1.1884641647338867, 1.1728270053863525, 1.1622772216796875]
        (list) [0.023866891860961914, 0.035660028457641602, 0.023386955261230469]
        

        【讨论】:

        • 有意思,python确实优化了初始化。我上了 ubuntu 9.04,python 2.6.2(我稍微截断了输出):(块中的数组)[0.0191,0.0180,0.0170](带生成器的数组)[0.9199,0.9179,0.6761](列表)[0.0069,0.0074 , 0.0064] 所以在我的机器列表上明显更快。 kaizer.se,你在运行什么操作系统/python?
        • 这是来自我古老的 iBook,一台 5 岁的笔记本电脑,运行 Debian/Linux 的 PowerPC G4,当然。毫无疑问,周围有更快的机器:-)
        • 我的意思不是比较我们的机器,而是比较机器上的时差。您的结果显示或多或少(块中的数组)与 (list) 的速度顺序相同,而在我的机器(或 python 实现)上, (list) 方法更快。
        • 哦,我真笨,忘记了一些信息,比如它在 Debian 上使用 Python 2.5.4。测试显示 Python 2.6 和 Python2.5 之间没有区别。
        • 最快的数组初始化是array.array('i', [0]) * count,因为它可以直接分配确切的内存大小而无需重新分配,也无需大的临时列表。见stackoverflow.com/a/3216322/448474
        【解决方案8】:
        import numpy as np
        
        new_array=np.linspace(0,10,11).astype('int')
        

        创建数组时转换类型的替代方法。

        【讨论】:

          猜你喜欢
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-20
          • 1970-01-01
          • 2020-03-01
          相关资源
          最近更新 更多