Python能否编写一行代码?

13

我正在浏览Stack Overflow上的代码高尔夫问题,并看到许多Perl一行解决方案。

在Python中能做到类似的吗?


2
是的???可能最好明确你想做什么... - Vincent Savard
2
适合发布在programmers.stackexchange.com上。 - SilentGhost
1
有很多带有cods-golf标签的Python一行代码。虽然没有Perl那么多,但我很惊讶你竟然一个都没看到。 - John La Rooy
是的,并且它被很好地实现了,可以将任何Python代码转换为一行代码 - https://github.com/csvoss/onelinerizer boom! - Fanglin
规范实际上是(尽管标题不是):“如何将多个语句放在一行中?”。其中一个答案直接讨论了Python中的一行代码的可行性。 - Peter Mortensen
8个回答

23

python -c 'print("是的。")'


17

在Python中编写一行代码是可能的,但有些别扭(Python鼓励缩进良好的代码,这与“一行代码”概念有些不一致)。在Python 3中更容易一些,因为 print()是一个函数而不是语句。以下是一个示例:

python -c "fact = lambda x: x * fact(x-1) if x > 1 else 1; print(fact(5))"

以下是一个类似于 grep 的函数实现(这个示例会打印输入中包含 "foo" 的行):

python -c "for s in __import__('fileinput').input(): __import__('sys').stdout.write(s) if 'foo' in s else None"

10

在使用 shell 进行操作时,我经常会想要这样做。但实际上,这并不会使代码更加简洁,而且在很多情况下,编写一个多行的 shell 命令比编写一个 lambda 表达式更容易。你几乎无法使用以冒号结尾的 Python 语句。因此,你最终不得不

  • write any for-like code as a genexp or list comprehension. I Do this anyway for most stuff, but it's annoying to have to import sys and push everything to sys.stdout.writelines in cases where you could otherwise just

     for tree in forest:
         print tree
    
  • write lambdas instead of function definitions. This is often workable and has the useful side effect of forcing you to write very directed functions that really only do one thing. However, it's not particularly convenient, and doesn't work for anything that mutates a value (e.g., dict.update) and then returns some element.

  • Do not bother doing things properly with context managers

  • Do not do any exception handling.

  • Use a dictionary of lambdas instead of any if/else sections.

  • Use type(name, bases, dict) to declare any classes. This is pretty fun but only works if you happen to be declaring a class whose methods can all be expressed as lambdas.

所以有些东西可以做到,但通常会很麻烦,因为你最终需要使用Python不真正支持的函数式风格。大多数时候,我只写多行shell命令,例如:

python -c $'
import some_module
for v in some_module.whatever():
    print "Whatever: \'{0}\'".format(v)
'
$'是一种bash引用语法,是其'...'"..."引用结构的替代品。它很有用,因为它像'...'一样工作,但允许您使用\'转义包含的'字符。您还可以嵌入换行符,因此上面的代码也可以写成python -c $'import some_module\nfor v in some_module.whatever():\n print "Whatever: \'{0}\'".format(v)'。然而,这有点需要习惯。
在bash中编写多行命令的一个烦人之处是HOMEEND会跳到命令的开头而不是行的开头。可能有更好的方法来解决这个问题,但我通常只是通过按住CTRL和左/右箭头键来来回扫描。一些Emacs用户可能能够帮助我,因为这是bash的正常键绑定所来自的地方。
如果您想在编辑多行命令时插入换行符,可以使用^V-^J来实现。这将以一种使您仍然可以扫描回先前行的方式插入换行符,而不是使用
$ first line of the command
> second line
> third line

如果你没有设置,就无法返回到之前的行,这个技巧在IPython中也适用,对于编辑类或函数定义非常有用。在基本的Python REPL中也可能有效;我不确定,因为我几乎总是使用IPython。


4
Bourne shell中,您可以使用称为heredoc的东西来避免Python对缩进的依赖:
python << 'EOF'
> for i in range(3):
>  print i
> EOF
0
1
2

2
不行,你缩进了 print。尝试不缩进它,你会得到一个 IndentationError,就像你应该得到的一样。 - aaronasterling
1
我表达不太准确。这使您能够缩进代码,而无需创建文件、打开编辑器等操作。 - S010
Python中并没有真正的“规避缩进依赖”的方法,因为这会使得编写大多数非平凡程序变得不可能。大多数读者想知道的是如何以一种单行方式指示缩进/取消缩进。 - Steven Lu
1
你可能只是指“满足Python对缩进的依赖”。 - Ken Williams

2
一个非常好的 Python 一行代码(指“相当有用”):
python -c 'import SimpleHTTPServer as foo; foo.test()'  23433

它在当前目录中创建一个即时的基础Web服务器。(我今天才刚了解它,非常方便。)


0
这是我运行多个语句的技巧: [stmt1, stmt2, expr1][2] 如果需要惰性求值: [lambda(): stmt1; lambda(): stmt2][not not boolExpr]()

这不是很清楚。也许可以加上一个(具体的,可运行的)例子? - Peter Mortensen

0
exec("if 6 * 9 == int('42', 13):\n\tprint('Yes!')")

采用这种方法,每个Python程序都可以写成一行代码 :)


-2

是的,实际上这很常见。当我需要编写快速代码时,我会使用一行代码。这取决于你想做什么。这是我今晚刚用过的一个小技巧。它可以在单行中创建一个Tkinter按钮。

a = Button(root, text="Button", command=com1).pack()

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