Python range()和zip()对象类型

时间:2013-11-04 21:36:14

标签: python python-3.x list iterator range

我理解如何在for循环中使用range()zip()等函数。但是我希望range()输出一个列表 - 就像unix shell中的seq一样。如果我运行以下代码:

a=range(10)
print(a)

输出为range(10),表明它不是列表而是不同类型的对象。 zip()在打印时具有类似的行为,输出类似

的内容
<zip object at "hexadecimal number">

所以我的问题是它们是什么,有什么优势使它们成为现实,以及如何在没有循环的情况下将它们输出到列表中?

3 个答案:

答案 0 :(得分:74)

您必须使用Python 3.

在Python 2中,对象ziprange确实按照您的建议行事,返回列表。它们被更改为generator - 类似于按需生成元素的对象,而不是将整个列表扩展到内存中。一个优点是它们的典型用例(例如迭代它们)的效率更高。

Python 2.x中也存在“懒惰”版本,但它们有不同的名称,即xrangeitertools.izip

要一次将所有输出检索到熟悉的列表对象中,您可以简单地调用list来迭代并使用内容:

>>> list(range(3))
[0, 1, 2]
>>> list(zip(range(3), 'abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]

答案 1 :(得分:20)

在Python 3.x.中,range返回一个范围对象而不是像Python 2.x中那样的列表。同样,zip现在返回一个zip对象而不是一个列表。

要将这些对象作为列表,请将它们放在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')]
>>>

虽然起初看起来似乎没有用,但rangezip行为的这种变化实际上提高了效率。这是因为zip和range对象会根据需要生成项目,而不是创建一个列表来同时保存它们。这样做可以节省内存消耗并提高操作速度。

答案 2 :(得分:3)

范围(python 2中的xrange *)对象是immutable sequences,而zip(itertools.izip分别是generator object。要从生成器或序列创建列表,只需转换为列表。例如:

>>> x = range(10) 
>>> list(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

但它们在元素生成方式上有所不同。正常生成器是可变的并且如果迭代则放弃它们的内容,而范围是不可变的,并且不是:

>>> 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!