2015-02-07 103 views
9

这是我的问题的简化示例。我认为,这些功能将具有完全相同的行为:奇怪的行为:功能的三元运算符

def f1(l): 
    if type(l[0][0])==list: f=lambda x:x[0][0] 
    else: f=lambda x:x[0] 
    l.sort(key=f,reverse=True) 

def f2(l): 
    f=lambda x:x[0][0] if type(l[0][0])==list else lambda x:x[0] 
    l.sort(key=f,reverse=True) 

l=[[1,2],[3,4]] 

但在现实中,当f2(l)不同之处坍塌f1(l)正常工作:

IndexError: list index out of range 

所以,问题是为什么会这样,是它可能使用返回其中一个函数的三元运算符?

+1

这是一种切线,但也许这是一种lambda使事情更容易阅读而不是更多的情况之一。如何检查'x'并返回'x [0]'或'x [0] [0]'或者你需要的任何'def getKey(x):'然后'l.sort(key = getKey,reverse = True)'。 – 2015-02-07 05:39:25

+0

@Asad是的,这是一个很好的观点,虽然它可能比原始版本慢一点。 – Nik 2015-02-07 06:16:17

+0

我不确定我明白为什么它会变慢。它避免了每次调用'f1'或'f2'时产生一个函数的开销,所以如果有任何事情它将会(无意义地)更高性能。我不会说这种差异值得担心。 – 2015-02-07 06:21:38

回答

8

lambdalowest precedence among operators。这就是为什么Python解析该行作为

f = lambda x: (x[0][0] if type(l[0][0]) == list else lambda x: x[0]) 

解决方法是在括号来包装各个lambda S:

f = (lambda x: x[0][0]) if type(l[0][0]) == list else (lambda x: x[0]) 

也就是说,type(l[0][0]) == list是有点不对,isinstance(l[0][0], list)将是最好的方式(也处理list的子类)。