我理解如何在for循环中使用range()
和zip()
等函数。但是我希望range()
输出一个列表 - 就像unix shell中的seq
一样。如果我运行以下代码:
a=range(10)
print(a)
输出为range(10)
,表明它不是列表而是不同类型的对象。 zip()
在打印时具有类似的行为,输出类似
<zip object at "hexadecimal number">
所以我的问题是它们是什么,有什么优势使它们成为现实,以及如何在没有循环的情况下将它们输出到列表中?
答案 0 :(得分:74)
您必须使用Python 3.
在Python 2中,对象zip
和range
确实按照您的建议行事,返回列表。它们被更改为generator - 类似于按需生成元素的对象,而不是将整个列表扩展到内存中。一个优点是它们的典型用例(例如迭代它们)的效率更高。
Python 2.x中也存在“懒惰”版本,但它们有不同的名称,即xrange
和itertools.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')]
>>>
虽然起初看起来似乎没有用,但range
和zip
行为的这种变化实际上提高了效率。这是因为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!