2010-07-24 47 views
3

我需要的元組下面的列表中的Python排序:Python的排序問題

ListOfTuples = [('10', '2010 Jan 1;', 'Rapoport AM', 'Role of antiepileptic drugs as preventive agents for migraine', '20030417'), ('21', '2009 Nov;', 'Johannessen SI', 'Antiepilepticdrugs in epilepsy and other disorders--a population-based study of prescriptions', '19679449'),...] 

我的目的是通過降序年(listOfTuples [2]),並通過升序作者(listOfTuples來訂購吧[2]):

sorted(result, key = lambda item: (item[1], item[2])) 

但它不起作用。我如何獲得排序穩定性?

+0

哪些是可能的日期格式?這裏我們看到「年/ monthabbr/day」和「year/monthabbr」。是否有可能只遇到「年」? – tokland 2010-07-24 15:41:49

+0

是的,因爲數據格式不規則。 – 2010-07-26 08:23:49

回答

4
def descyear_ascauth(atup): 
    datestr = atup[1] 
    authstr = atup[2] 
    year = int(datestr.split(None, 1)[0]) 
    return -year, authstr 

... sorted(result, key=descyear_ascauth) ... 

注意:您需要提取一年的整數(而不是作爲一個字符串),這樣就可以改變其標誌 - 後者是關鍵訣竅,以滿足規範中的「降序」部分。在lambda範圍內全部壓縮都是可能的,但是當def工作的很好(而且更易讀)時,絕對沒有理由這樣做,並犧牲更多的可讀性。

+0

Grazie mille,sei semper gentilissimo! :)我應該使用什麼方法來添加另一個訂單鍵,如「月」?我應該將月份的名稱映射爲字典('jan':1,'feb:2')嗎? – 2010-07-24 15:39:53

+0

@Gianluca,使用明確的字典給你完全控制,因此我會推薦。你可以使用'list(calendar.month_name)'來玩這個詞典,例如以一種與語言環境相關的方式,但除非您在這個方面有非常特殊的需求,否則它的複雜程度要遠遠高於保證值。 – 2010-07-24 17:55:22

+0

感謝您的回答:)。現在我無法決定選擇哪個答案,因爲@Duncan在我的問題上發佈了一個工作方法。到目前爲止,這是一個味道(可讀性與緊湊性)和性能(使用「技巧」與「做Python方式」)...... – 2010-07-24 18:14:34

0

這裏是一切工作的成語,甚至一件事情你不能否定,例如字符串:

data = [ ('a', 'a'), ('a', 'b'), ('b','a') ] 

def sort_func(a, b): 
    # compare tuples with the 2nd entry switched 
    # this inverts the sorting on the 2nd entry 
    return cmp((a[0], b[1]), (b[0], a[1])) 

print sorted(data)     # [('a', 'a'), ('a', 'b'), ('b', 'a')] 
print sorted(data, cmp=sort_func)  # [('a', 'b'), ('a', 'a'), ('b', 'a')] 
+0

'cmp'不再適用於Python 3,雖然在functools中有'cmp_to_key'。 – kennytm 2010-07-24 15:56:44

2

最簡單的方法是分別排序每個鍵值。從最不重要的關鍵開始,一路走到最重要的位置。

因此,在這種情況下:

import operator 
ListOfTuples.sort(key=operator.itemgetter(2)) 
ListOfTuples.sort(key=lambda x: x[1][:4], reverse=True) 

這工作,因爲Python的排序總是穩定的,甚至當你使用反轉標記:即反向不只是排序,然後反向(這會失去穩定性,它保留倒車後的穩定性。

當然,如果你有很多鍵列的這可能是低效的,因爲它不完整的排序幾次。

您不必當年轉換爲數字這種方式它是一種真正的反向排序,你你可以,如果你想。

+0

您的解決方案非常緊湊且pythonic,但@ Alex's更快。無法決定誰是贏家:) – 2010-07-24 18:07:40

0

這裏有一個粗略的解決方案,需要一個月abbreviature和日(如果找到)帳戶:

import time 
import operator 

def sortkey(seq): 
    strdate, author = seq[1], seq[2] 
    spdate = strdate[:-1].split() 
    month = time.strptime(spdate[1], "%b").tm_mon 
    date = [int(spdate[0]), month] + map(int, spdate[2:]) 
    return map(operator.neg, date), author 

print sorted(result, key=sortkey) 

「%B」是語言環境的縮寫月份名稱,你可以使用字典,如果你不喜歡對付語言環境。

0

這是Alex的答案的lambda版本。我認爲它現在看起來比鄧肯的答案更加緊湊,但顯然Alex的答案很多可讀性已經丟失。

sorted(ListOfTuples, key=lambda atup: (-int(atup[1].split(None, 1)[0]), atup[2])) 

可讀性和效率通常應該優先考慮緊湊性。