(2010 年 11 月 23 日 19:48 回答)
我不是一个真正的 Pythoner - 但我曾经发现过这种语法,忘记了从哪里来,所以我想我会记录它:
如果您使用 sys.stdout.write 而不是 print(不同之处在于,sys.stdout.write 将参数作为函数,在括号中 - 而 print 没有),然后单行,您可以通过反转命令和for 的顺序,删除分号并将命令括在方括号中,即:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
不知道如何在 Python 中调用此语法:)
希望对你有帮助,
干杯!
(2013 年 4 月 9 日星期二 20:57:30 编辑) 好吧,我想我终于找到了单行中的这些方括号的含义;它们是“列表理解”(显然);首先在 Python 2.7 中注意这一点:
$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>
因此圆括号/括号中的命令被视为“生成器对象”;如果我们通过调用 next() 来“迭代”它 - 那么括号内的命令将被执行(注意输出中的“abc”):
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>
如果我们现在使用方括号 - 请注意,我们不需要调用 next() 来执行命令,它会在分配后立即执行;然而,后来检查发现a 是None:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
对于方括号的情况,这并没有留下太多信息可供查找 - 但我偶然发现了这个页面,我认为它可以解释:
Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:
如果您还记得,单行生成器的标准格式是括号内的一种单行“for”循环。这将产生一个“一次性”可迭代对象,该对象只能在一个方向上进行迭代,并且一旦到达终点就无法重复使用。
“列表推导式”看起来与常规的单行生成器几乎相同,除了常规括号 - ( ) - 被方括号 - [ ] 替换。 alist 理解的主要优点是生成一个“列表”,而不是一个“一次性”可迭代对象,以便您可以在它中来回切换、添加元素、排序等。
确实它是一个列表——它只是它的第一个元素在执行后立即变为无:
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None
列表推导式在5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation 中另有说明,因为“列表推导式提供了一种创建列表的简洁方式”;据推测,这就是列表的有限“可执行性”在单行中发挥作用的地方。
好吧,希望我在这里不会太离谱......
EDIT2:这是一个带有两个非嵌套 for 循环的单行命令行;都包含在“列表理解”方括号内:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]
请注意,第二个“列表”b 现在有两个元素,因为它的 for 循环显式运行了两次;然而,sys.stdout.write() 在这两种情况下的结果都是(显然)None。