Python range() 和 zip() 对象类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19777612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python range() and zip() object type
提问by Michal
I understand how functions like range()
and zip()
can be used in a for loop. However I expected range()
to output a list - much like seq
in the unix shell. If I run the following code:
我了解如何在 for 循环中使用range()
和zip()
使用函数。但是我希望range()
输出一个列表 - 就像seq
在 unix shell 中一样。如果我运行以下代码:
a=range(10)
print(a)
The output is range(10)
, suggesting it's not a list but a different type of object. zip()
has a similar behaviour when printed, outputting something like
输出为range(10)
,表明它不是列表而是不同类型的对象。zip()
打印时有类似的行为,输出类似
<zip object at "hexadecimal number">
So my question is what are they, what advantages are there to making them this, and how can I get their output to lists without looping over them?
所以我的问题是它们是什么,使它们成为这个有什么优势,以及如何在不循环的情况下将它们的输出添加到列表中?
采纳答案by wim
You must be using Python 3.
您必须使用 Python 3。
In Python 2, the objects zip
and range
did behave as you were suggesting, returning lists. They were changed to generator-like objects which produce the elements on demand rather than expand an entire list into memory. One advantage was greater efficiency in their typical use-cases (e.g. iterating over them).
在 Python 2 中,对象zip
和range
确实按照您的建议行事,返回列表。它们被更改为类似生成器的对象,可以按需生成元素,而不是将整个列表扩展到内存中。一个优势是在他们的典型用例中效率更高(例如迭代它们)。
The "lazy" versions also exist in Python 2.x, but they have different names i.e. xrange
and itertools.izip
.
“懒惰”版本也存在于 Python 2.x 中,但它们具有不同的名称,即xrange
和itertools.izip
.
To retrieve all the output at once into a familiar list object, you may simply call list
to iterate and consume the contents:
要将所有输出一次检索到熟悉的列表对象中,您可以简单地调用list
迭代并使用内容:
>>> list(range(3))
[0, 1, 2]
>>> list(zip(range(3), 'abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
回答by Michal
In Python 3.x., range
returns a range object instead of a list like it did in Python 2.x. Similarly, zip
now returns a zip object instead of a list.
在 Python 3.x. 中,range
返回一个范围对象而不是像在 Python 2.x 中那样的列表。同样,zip
现在返回一个 zip 对象而不是一个列表。
To get these objects as lists, put them in list
:
要将这些对象作为列表获取,请将它们放入list
:
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> zip('abc', 'abc')
<zip object at 0x01DB7120>
>>> list(zip('abc', 'abc'))
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>>
While it may seem unhelpful at first, this change in the behavior of range
and zip
actually increases efficiency. This is because the zip and range objects produce items as they are needed, instead of creating a list to hold them all at once. Doing so saves on memory consumption and improves operation speed.
虽然它可能在最初看起来无益,这种变化的行为range
,并zip
真的提高了效率。这是因为 zip 和 range 对象会根据需要生成项目,而不是创建一个列表来一次性保存所有项目。这样做可以节省内存消耗并提高操作速度。
回答by alko
Range (xrange
in python 2.*) objects are immutable sequences, while zip (itertools.izip
repectively) is a generator object. To make a list from a generator or a sequence, simply cast to list. For example:
Range(xrange
在 python 2.* 中)对象是不可变序列,而 zip(分别itertools.izip
)是一个生成器对象。要从生成器或序列制作列表,只需将其转换为列表即可。例如:
>>> x = range(10)
>>> list(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
But they differ in a way how elements are generated. Normal generators are mutable and exaust their content if iterated, while range is immutable, and don't:
但是它们在元素的生成方式上有所不同。普通生成器是可变的,如果迭代就耗尽它们的内容,而范围是不可变的,并且不要:
>>> list(x) # x is a range-object
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # second cast to list, contents is the same
>>> y = zip('abc', 'abc')
>>> list(y) # y is a generator
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>> list(y)
[] # second cast to list, content is empty!