range() 真的会创建列表吗? [英] Does range() really create lists?

查看:38
本文介绍了range() 真的会创建列表吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的教授和这个人都声称range 创建一个值列表.

<块引用>

"注意:range 函数只返回一个包含数字的列表从 x 到 y-1.例如,range(5, 10) 返回列表 [5, 6, 7, 8,9]."

我认为这是不准确的,因为:

type(range(5, 10))<类范围">

此外,访问由 range 创建的整数的唯一明显方法是遍历它们,这让我相信将 range 标记为列表是不正确的.

解决方案

在 Python 2.x 中,range 返回一个列表,但在 Python 3.x range 返回一个不可变序列,类型为 range.

Python 2.x:

<预><代码>>>>类型(范围(10))<输入列表">>>>类型(xrange(10))<输入'xrange'>

Python 3.x:

<预><代码>>>>类型(范围(10))<类范围">

在 Python 2.x 中,如果你想获得一个可迭代对象,比如在 Python 3.x 中,你可以使用 xrange 函数,它返回类型为 xrange.

xrange 在 Python 2.x 中相对于 range 的优势:

<块引用>

xrange() 相对于 range() 的优势是微乎其微的(因为 xrange() 仍然需要在需要时创建值它们)除非在内存不足的机器上使用非常大的范围或从不使用范围的所有元素时(例如当循环通常以 break 终止时).

注意:

<块引用>

此外,访问由 range() 创建的整数的唯一明显方法是遍历它们,

没有.由于 Python 3 中的 range 对象是不可变序列,因此它们也支持索引.引用 range 函数文档,

<块引用>

Ranges 实现了除连接和重复之外的所有常见序列操作

...

Range 对象实现了 collections.abc.Sequence ABC,并提供包含测试、元素索引查找、切片和支持负索引等功能.

例如

<预><代码>>>>范围(10, 20)[5]15>>>范围(10, 20)[2:5]范围(12, 15)>>>列表(范围(10, 20)[2:5])[12, 13, 14]>>>列表(范围(10、20、2))[10, 12, 14, 16, 18]>>>18 范围内 (10, 20)真的>>>100 范围内 (10, 20)错误的

所有这些都可以通过不可变的 range 序列实现.


最近,我遇到了一个问题,我认为将其包含在这里是合适的.考虑这个 Python 3.x 代码

from itertools import islice数字 = 范围(100)项目 = 列表(islice(数字,10))而项目:项目 = 列表(islice(数字,10))打印(项目)

人们希望这段代码每十个数字打印一个列表,直到 99.但是,它会无限运行.你能说出原因吗?

解决方案

因为 range 返回一个不可变的 sequence,而不是一个迭代器对象.因此,每当在 range 对象上执行 islice 时,它总是从头开始.将其视为不可变列表的替代品.现在问题来了,你将如何解决它?很简单,你只需要从中得到一个迭代器.只需改变

numbers = range(100)



numbers = iter(range(100))

现在,numbers 是一个迭代器对象,它会记住它之前被迭代了多长时间.所以,当 islice 迭代它时,它只是从它之前结束的地方开始.

Both my professor and this guy claim that range creates a list of values.

"Note: The range function simply returns a list containing the numbers from x to y-1. For example, range(5, 10) returns the list [5, 6, 7, 8, 9]."

I believe this is to be inaccurate because:

type(range(5, 10))
<class 'range'>

Furthermore, the only apparent way to access the integers created by range is to iterate through them, which leads me to believe that labeling range as a lists is incorrect.

解决方案

In Python 2.x, range returns a list, but in Python 3.x range returns an immutable sequence, of type range.

Python 2.x:

>>> type(range(10))
<type 'list'>
>>> type(xrange(10))
<type 'xrange'>

Python 3.x:

>>> type(range(10))
<class 'range'>

In Python 2.x, if you want to get an iterable object, like in Python 3.x, you can use xrange function, which returns an immutable sequence of type xrange.

Advantage of xrange over range in Python 2.x:

The advantage of xrange() over range() is minimal (since xrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the range’s elements are never used (such as when the loop is usually terminated with break).

Note:

Furthermore, the only apparent way to access the integers created by range() is to iterate through them,

Nope. Since range objects in Python 3 are immutable sequences, they support indexing as well. Quoting from the range function documentation,

Ranges implement all of the common sequence operations except concatenation and repetition

...

Range objects implement the collections.abc.Sequence ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices.

For example,

>>> range(10, 20)[5]
15
>>> range(10, 20)[2:5]
range(12, 15)
>>> list(range(10, 20)[2:5])
[12, 13, 14]
>>> list(range(10, 20, 2))
[10, 12, 14, 16, 18]
>>> 18 in range(10, 20)
True
>>> 100 in range(10, 20)
False

All these are possible with that immutable range sequence.


Recently, I faced a problem and I think it would be appropriate to include here. Consider this Python 3.x code

from itertools import islice
numbers = range(100)
items = list(islice(numbers, 10))
while items:
    items = list(islice(numbers, 10))
    print(items)

One would expect this code to print every ten numbers as a list, till 99. But, it would run infinitely. Can you reason why?

Solution

Because the range returns an immutable sequence, not an iterator object. So, whenever islice is done on a range object, it always starts from the beginning. Think of it as a drop-in replacement for an immutable list. Now the question comes, how will you fix it? Its simple, you just have to get an iterator out of it. Simply change

numbers = range(100)

to

numbers = iter(range(100))

Now, numbers is an iterator object and it remembers how long it has been iterated before. So, when the islice iterates it, it just starts from the place where it previously ended.

这篇关于range() 真的会创建列表吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆