应用于三元运算符参数的一元运算符的用法(例如,应用于字符串的 * 运算符参数)
Posted
技术标签:
【中文标题】应用于三元运算符参数的一元运算符的用法(例如,应用于字符串的 * 运算符参数)【英文标题】:Usage of unary operators applied to ternary operator arguments (eg *operator argument applied to string) 【发布时间】:2015-02-04 02:15:19 【问题描述】:这就是我正在做的事情:
def func(a,b=1,*args):
print('a:',a,'b:',b,'args:',*args if args else 'No args')
func(1,2)
这是我的预期:
#a:1 b: 2 args: No args
这是我实际得到的:
#a:1 b: 2 args: N o a r g s
*
运算符正在解压'No args'
字符串。所以这就是我应该做的:
#Produces expected result:
def func(a,b=1,*args):
print('a:',a,'b:',b,'args:',*args if args else ['No args'])
所以*
运算符被应用于整个三元语句。但是-
运算符似乎不会发生这种情况:
def func(a,b=1,*args):
print('a:',a,'b:',b,'negative args[0]:', -args[0] if args else 1000000)
func(1,2)
#expected result:
#a:1 b: 2 negative args[0]: -1000000
#actual result:
#a:1 b: 2 negative args[0]: 1000000
否定的-
运算符不适用于整个三元语句,而*
运算符则适用。为什么? *
运算符有什么特别之处?
【问题讨论】:
【参考方案1】:编辑:我更改了问题,但由于下面的有用评论,我将把这个答案留在这里。修改后的问题的答案可以总结如下:
“运算符优先级,假人。”
啊哈!我应该多做一些实验:
def func(a,b=1,*args):
print('a:',a,'b:',b,'args:',*args if args else ['No args'])
func(1,2)
结果如预期:
#a: 1 b: 2 args: No args
【讨论】:
我怀疑有没有比这个更干净的方法。明星applies to the entire argument,所以你不能只写(*args) if args...
之类的东西。【参考方案2】:
您已经在your own answer 中找到了编写代码的正确方法:
def func(a,b=1,*args):
print('a:',a,'b:',b,'args:',*args if args else ['No args'])
但这并不能回答您关于“*
运算符有什么特别之处”的问题。
首先要注意的是*
实际上根本不是一个运算符,它是function call syntax 的一部分。但是在松散的对话中(包括在实际文档中),它通常被称为“splat 运算符”,所以这并不是一个很好的答案。 (conditional expressions 也是如此,它也不是运算符表达式,但它仍然经常被称为“三元运算符”或“if-else 运算符”。)
但是,更重要的是,如果您想将*
和… if … else …
(松散地)视为运算符,则必须考虑运算符优先级。三元运算符只是比 splat 运算符绑定得更紧密,而它并没有比否定运算符绑定得更紧密。
所以,这就像在编写 2 / 3 * 5
和 2 - 3 * 5
时问“/
运算符有什么特别之处”。 -
适用于整个 3 * 5
,但 /
仅适用于 3
,因为运算符优先。
【讨论】:
感谢您对您的回答非常友善和解释性,这基本上是(而且是正确的!):“它就是这样。” ;) @RickTeachey:嗯,在某种程度上,任何语言的运算符优先规则都是任意的。但实际上,语言设计者试图提出优先规则,使事情更容易阅读。 (Python 的设计者还添加了一个额外的约束,试图使优先规则简单和极简,所以当它不明显时,至少很容易记住。)以上是关于应用于三元运算符参数的一元运算符的用法(例如,应用于字符串的 * 运算符参数)的主要内容,如果未能解决你的问题,请参考以下文章