需要了解range(0,2)
和list(range(0,2))
之间的区别,使用python2.7
两者都返回一个列表,那究竟是什么区别呢?
答案 0 :(得分:34)
在Python 3.x中,
range(0,3)
返回一类不可变的可迭代对象,让你迭代它们,它不会产生列表,并且它们不会将范围内的所有元素存储在内存中,而是会动态生成元素(当你迭代它们时),而list(range(0,3))
产生一个列表(通过迭代所有元素并在内部追加到列表中)。
示例 -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
理想情况下,如果您只想迭代该范围的值,range(0,3)
将比(list(range(0,3))
更快,因为后者在开始迭代之前会产生列表的开销。
在Python 2.x中,range(0,3)
生成一个列表,而我们还有一个xrange()
函数,它具有与Python 3.x相似的range()
函数行为(xrange已重命名为Python 3.x中的范围
对于Python 3.5,来自documentation -
Range对象实现collections.abc.Sequence ABC,并提供包含测试,元素索引查找,切片和支持负索引等功能
所以你可以做像 -
这样的事情>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
所有这些都是恒定时间操作,从这个测试中可以看出 -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
答案 1 :(得分:12)
这取决于您使用的Python版本。
在Python 2.x中,range()
返回一个列表,因此它们是等效的。
在Python 3.x中,range()
返回一个不可变的序列类型,需要list(range(0,2))
来获取列表。
答案 2 :(得分:2)
这两个命令都返回Python2.x中的列表。但是在Python3.x中,range是一个不可变的序列,不会返回列表。它用于迭代广告循环
答案 3 :(得分:1)
在python3.x中,range有自己的类型
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>
因此,如果你想在for循环中使用range(),那很好。但是,您不能将它purely
用作列表对象。您需要将其转换为列表才能执行此操作。
Python2示例:
>>> L = range(10)
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Python3示例:
>>> L = range(10)
>>> L[::-1]
range(9, -1, -1)
答案 4 :(得分:1)
基本上,区别在于range(0, 2)
是生成器函数,list(range(0, 2))
是实际列表。
循环中使用生成器函数。例如,文件的生成器函数将逐行读取非常大的文件。
def gen():
for line in open("hugefile.csv", "r"):
yield line #Gives back the line every time it is read, but forgets that line after
for line in gen():
print(line)
这将打印每一行而不会使计算机的RAM过载,因为您只是在两个函数中逐个读取。但是,如果我们做类似
的事情def readEntireFile():
return [line for line in open("hugefile.csv", "r")] #Python has lazy ways of making lists, this is the same as returning a list with all the lines in the file
for line in readEntireFile():
print(line)
第二部分看起来一样,但事实并非如此。最初,我们循环遍历文件中的每一行,并在完成后继续前进到下一行。在这里,Python有一个所有行的列表:/,想象用10GB文件做到这一点!你的代码会崩溃。
现在,让我们回到range()和list(range())
执行for x in range(0, 6):
会让我们转到范围中的下一个数字并完全忘记前一个(螺旋语法)。
然而,执行for x in list(range(0, 6)):
会将整个数字列表保留在内存中并与执行相同
numlist = [x for x in range(6)]
for x in numlist:
print(x)
如果需要代码中的整个数据列表,请使用list方法。但是,当您一次只需要一个数据时(最简单的例子,以块的形式复制文件),使用生成器函数来节省空间。您可以使用仅54 MB的文件复制每100万行文件(假设您没有疯狂的长行)。但是,如果我们有一个小的2kb文件,我们可以在没有生成器的情况下复制那个东西。这不值得花时间,在这种情况下速度较慢。
答案 5 :(得分:1)
Range 生成类 'range' 的对象
是否持久取决于是否赋值
a = range(10)
print(type(a))
print(a[0])
print(type(a[0]))
输出:
<class 'range'>
0
<class 'int'>
输出在功能上是一个不可变的有序整数容器。
从语义上讲,它是一个整数元组,但为了提高效率,Python 将其实现为一个单独的“生成器”类,而不是类元组。
这是一个很好的例子,说明 Python 在缺乏编译的情况下无法隐藏实现细节,程序员必须意识到它们。