Python中的range()函数和Numpy库中的arange()函数有什么区别?

3

我在网上搜索发现,numpy.arange比python的range函数占用更少的空间。但是当我尝试使用以下代码时,结果与range函数不同。

import sys

x = range(1,10000)
print(sys.getsizeof(x))  # --> Output is 48

a = np.arange(1,10000,1,dtype=np.int8)
print(sys.getsizeof(a))  # --> OutPut is 10095

请问有人可以解释一下吗?


不要指望 getsizeof() 能够给你复杂对象的完整内存使用情况。 - Klaus D.
1
您可以参考:https://muddoo.com/tutorials/difference-between-range-vs-arange-in-python/ - David
@KlausD。range对象非常简单,只有三个整数引用。 - juanpa.arrivillaga
你是否阅读过这两个函数的实际文档?这总是比随机搜索网络更好的起始方法。 - Mad Physicist
什么是上下文? - hpaulj
3个回答

3
在PY3中,range是一个能够生成数字序列的对象,而不是实际的序列。你可能需要复习一些基本的Python知识,特别是列表和生成器及它们之间的区别。
In [359]: x = range(3)                                                                                 
In [360]: x                                                                                            
Out[360]: range(0, 3)

我们可以使用类似于list或列表推导式来创建这些数字:
In [361]: list(x)                                                                                      
Out[361]: [0, 1, 2]
In [362]: [i for i in x]                                                                        
Out[362]: [0, 1, 2]

在类似于 for i in range(3): print(i) 的循环中,常常使用范围。

arange 是一个 numpy 函数,它生成一个 numpy 数组:

In [363]: arr = np.arange(3)                                                                           
In [364]: arr                                                                                          
Out[364]: array([0, 1, 2])

我们可以遍历这样的数组,但它比[362]慢。
In [365]: [i for i in arr]                                                                             
Out[365]: [0, 1, 2]

但是对于数学计算,数组更好:

In [366]: arr * 10                                                                                     
Out[366]: array([ 0, 10, 20])

数组还可以从列表[361](为了与早期 Py2 的使用兼容,也可以从 range 本身创建)中创建:
In [376]: np.array(list(x))     # np.array(x)                                                                        
Out[376]: array([0, 1, 2])

但是,与直接使用arange相比,这种方法速度较慢(这是一个实现细节)。
尽管名称相似,但这些不应被视为简单的替代品。在基本的Python结构中,如for循环和推导式中使用range。当您需要数组时,请使用arange
Python中的一个重要创新(与早期语言相比)是我们可以直接在列表上进行迭代。我们不必逐个索引进行迭代。如果我们需要值以及它们的索引,我们可以使用enumerate
In [378]: alist = ['a','b','c']                                                                        
In [379]: for i in range(3): print(alist[i])   # index iteration                                                        
a
b
c
In [380]: for v in alist: print(v)    # iterate on list directly                                       
a
b
c
In [381]: for i,v in enumerate(alist): print(i,v)    #  index and values                                                  
0 a
1 b
2 c

因此,在基本的Python代码中,您可能不会经常看到range被使用。

非常有用的深入探讨。也许可以将np.array(10*list(range(5)))10*np.array(list(range(5)))进行比较,以展示如何从现有列表正确创建带数学运算的数组。 - P2000

1
range类型构造函数创建range对象,这些对象以高效的方式表示具有起始、停止和步骤的整数序列,并在计算时动态生成值。 np.arange函数返回一个numpy.ndarray对象,它实际上是原始数组的包装器。与创建Python list(例如list(range(N)))相比,这是一种快速且相对紧凑的表示形式,但range对象更加节省空间,实际上只需要常量空间,因此,对于所有实际目的而言,range(a)与任何整数a、b的range(b)大小相同。
顺便提一下,您应该注意解释sys.getsizeof的结果,必须理解它正在做什么。因此,不要简单地比较Python列表和numpy.ndarray的大小。
也许您阅读的内容是指Python 2,在那里range返回一个list。与一般情况下的numpy.ndarray对象相比,列表对象需要更多的空间。

1
arange 存储数组的每个单独值,而 range 只存储 3 个值(起始值、结束值和步长)。这就是为什么相比于 rangearange 占用更多的空间。
由于问题涉及到大小,这将是答案。
但是,从速度、空间和效率的角度来看,使用 numpy 数组和 arange 比使用 Python 列表有许多 优点

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