2012-02-14 65 views
3

我有一段奇怪的代碼。這是臭的,但我想不出如何更清晰的方式。如何鏈優雅

我想要做的是從左列表的尾部或右列表中刪除最大的項目。我結束了這個代碼。

if not left: 
    right.pop(0) 
elif not right: 
    left.pop(-1): 
elif len(left[-1]) < len(right[0]): 
    right.pop(0) 
else: 
    left.pop(-1) 

條件的身體是彼此精確重複,惡作劇。

有沒有一種優雅的方式來重構此代碼以減少重複?

+0

對不起爲蹩腳的標題,隨時提高它。 – 2012-02-14 02:33:58

+2

這聽起來像你需要[這個模塊](http://entrian.com/goto/)(只是在開玩笑) – wim 2012-02-14 02:47:59

+2

重複一個襯墊對我來說似乎並不是太糟糕的「重複」。我比目前發佈的所有備用表單更喜歡你的代碼。 – 2012-02-14 02:58:50

回答

6

連鎖你的條件,而不是多餘的條款。

if (not left) or (right and (len(left[-1]) < len(right[0]))): 
    right.pop(0) 
else: 
    left.pop(-1) 
+11

這似乎比原來的代碼更難讀,因爲我必須停下來思考嵌套布爾邏輯的含義。 – 2012-02-14 02:36:50

+0

@Greg:你沒有錯,但必須在某處嵌套*。 – 2012-02-14 02:39:39

4

這項工作?

>>> left_len = len(left[-1]) if left else -1 
>>> right_len = len(right[0]) if right else -1 
>>> right.pop(0) if right_len > left_len else left.pop(-1) 
9 

的行爲是有點不同,在如果not left and not rightleft.pop(-1)代替right.pop(0)。不過,這是一個錯誤無論哪種方式...

+1

我以爲一樣,但它應該更像'else -1'。 – 2012-02-14 02:47:29

+0

@NiklasB。,是的,沒錯。 – senderle 2012-02-14 02:49:33

1

一些哈克的方法(​​即一致,以便更爲通用一點的好,因爲它可以擴展到超過2所列出):

_, lst, i = max((len(lst[i]), lst,i) for lst,i 
       in ((left, -1), (right, 0)) if lst) 
lst.pop(i) 
+0

+1純屬不可思議。 :)但是這個怎麼樣?如果lst),key = lambda x:len(x [0] [x [lst,i)), 1]]))' – senderle 2012-02-14 03:10:56

+0

@senderle:其實我也是這麼想的!但是當我試用它時,時間更長了,所以我不想添加它:P – 2012-02-14 03:13:31

1
left_tail_size = len(left[-1]) if left else 0 
right_head_size = len(right[0]) if right else 0 

if left_tail_size >= right_head_size: 
    left.pop(-1) 
else: 
    right.pop(0) 
+0

應該是'else -1',但除了那個bug之外,它與senderle的答案几乎相同。 – 2012-02-14 03:15:56