2015-02-07 45 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的子類)。