2016-07-07 47 views
0

在Python 2,假設排序拉鍊,我們有兩個列表:的Python:根據長度和重量

list1 = [["A"],["A","B"],["B","D"],["C"],["A","B","D"]] 
list2 = [5,10,10,15,10] 

我想基於下降列表2(權重),每當排序列表1的兩個項目的權重是相同的(例如,x = [「A」,「B」,「D」]和y = [「B」,「D」]的重量都是10),長度較大的那個首先出現。對於列表1和表2,我所要的輸出如:

[["C"], ["A","B","D"], ["A","B"],["B","D"],["A"]]

這怎麼可能?

我所知道的是,我們可以通過先定義

zipped = zip(list1,list2) 

,然後僅基於大小對它們進行排序:

zipped.sort(key=lambda t: t[1],reverse=True) 
+1

我想你的意思是你想根據list2排序'list1'而不是你寫的方式。 –

+0

@BurhanKhalid你是對的。編輯。 –

+0

好的第一步。現在你有什麼嘗試其餘的? – Julien

回答

5

爲了通過幾個參數的key函數返回一個排序元組:

In [6]: sorted(zip(list1, list2), key=lambda x: (x[1], len(x[0])), reverse=True) 
Out[6]: 
[(['C'], 15), 
(['A', 'B', 'D'], 10), 
(['A', 'B'], 10), 
(['B', 'D'], 10), 
(['A'], 5)] 

應該讀取key=lambda x: (x[1], len(x[0]))作爲「首先按x [1]中的權重排序,然後按x [0]」中的列表長度排序。

爲了檢索每個元組第一個元素,你可以換的結果變成一個列表理解:

In [7]: [x[0] for x in sorted(zip(list1, list2), key=lambda x: (x[1], len(x[0])), reverse=True)] 
Out[7]: [['C'], ['A', 'B', 'D'], ['A', 'B'], ['B', 'D'], ['A']] 
+0

偉大的思想思考。 :) –

+1

@ PM2Ring,當然,但這也是一個Python的禪宗的一部分:*「應該有一個 - 最好只有一個 - 明顯的方法來做到這一點。」* :) – soon

+0

@soon謝謝,我didn不知道我們可以在「關鍵」中給出多個標準的事實。 –

3

你的關鍵功能需要告訴sort檢查時list2權重是list1項目的長度相同。你可以做到這一點通過將關鍵的元組,像這樣:

list1 = [["A"],["A","B"],["B","D"],["C"],["A","B","D"]] 
list2 = [5,10,10,15,10] 

zipped = zip(list1,list2) 

zipped.sort(key=lambda t: (t[1], len(t[0])), reverse=True) 

print(list(zip(*zipped)[0])) 

輸出

[['C'], ['A', 'B', 'D'], ['A', 'B'], ['B', 'D'], ['A']] 

FWIW,這裏是一個將在Python 3和Python 2.我的工作版本以前的代碼在Python 3中不起作用,因爲Python 3 zip返回一個迭代器,而不是一個列表。

zipped = zip(list1, list2) 
zipped = sorted(zipped, key=lambda t: (t[1], len(t[0])), reverse=True) 
newlist = [t[0] for t in zipped] 
print(newlist) 
+0

@soon感謝您的完整回覆。 –