“range(0,2)”和“list(range(0,2))”之间有什么区别?

时间:2015-07-05 05:53:37

标签: python python-2.7 python-3.x

需要了解range(0,2)list(range(0,2))之间的区别,使用python2.7

两者都返回一个列表,那究竟是什么区别呢?

6 个答案:

答案 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 在缺乏编译的情况下无法隐藏实现细节,程序员必须意识到它们。