Python 3打印生成器

8

我在使用print()函数(Python 3)时遇到了问题。

当我要求一系列数的总和时,可以使用以下代码模式:

>>> sum(i for i in range(101))

但是当我想要检查我所做的系列时:(我选择使用print()函数,假设它会逐行打印)

>>> print(i for i in range(101))

原来生成器对象没有返回值。因此,我必须使用list()进行系列检查。这是打印函数中的一个缺陷吗?

备注:上面所述的是形成生成器的示例,不是自然序列的最简形式,而是复杂序列的骨架。为了方便序列值的检查,我正在寻找一种逐行打印每个值的方法。

2个回答

14

sum 接收一个可迭代的对象作为参数进行求和,而 print 接收分离的参数进行打印。如果你想单独地将生成器中的所有项提供给 print,可以使用 * 表示:

print(*(i for i in range(1, 101)))

其实在这两种情况下你都不需要使用生成器:

sum(range(1, 101))
print(*range(1, 101))

如果您想让它们分别显示在不同行上,那么您期望的是多次单独调用 print 的行为,这意味着您期望得到一个普通循环的行为:
for item in generator_or_range_or_whatever:
    print(item)

尽管您也可以选择将'\n'指定为项目分隔符:
print(*generator_or_range_or_whatever, sep='\n')

1
这很有趣,因为就我所知,Python2.x的打印语句没有类似的行为。我投+1赞成。 - mgilson
@mgilson:嗯,总是可以使用“from future import print_function”,但是对于语句版本,没有类似的东西。 - user2357112
是的 - 我确实考虑过那个...我的意思更多的是,这是一个有趣的用例,对于一个你无法通过打印语句得到的打印函数。 - mgilson
@nobody:如果你想逐行查看它们,你只需要一个普通的for循环。 - user2357112
1
如果你想逐行打印它们,你也可以一次性打印并将 sep 关键字参数设置为 '\n' - Karl Knechtel
显示剩余10条评论

1
这种行为与Python 2.x上的行为并没有太大的区别:
Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> print (i*i for i in range(30))
<generator object <genexpr> at 0x10c034a50>

一般来说,如果您想真正了解项目,列表可能是最简单的方法(只需要添加几个方括号即可:

print [i*i for i in range(30)]

或者在Python3.x上:
print([i*i for i in range(30)])

我能否指出[i for i in range(30)]等同于range(30),并且编写它类似于编写if x>3 == True:。因此你可以编写print range(30)print(range(30)) - holdenweb
@holdenweb print([range(20)]) 也会返回一个生成器对象的列表。因此,唯一的解决方案是展开并编写 for i in .. - Vivek Rai
@holdenweb 这又是2.x和3.x之间的区别。2.x的range是创建列表的函数;3.x的range是类似于2.x的xrange但具有一些额外的功能。 - Karl Knechtel
@mgilson 谢谢您的回复,不必担心迭代问题,因为我打算以任何方式展示生成器案例(因为“简单胜于复杂”是Python之禅),我宁愿给出一个简单的例子,而不是“复杂到适合最简单”的例子。 - nobody
@holdenweb -- 这很正确。[i for i in ...]通常不是你想使用的东西。我只是用它作为列表推导/生成器表达式的一个例子,因为没有更好的例子。 - mgilson
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接