2015-07-13 61 views
-2

我有一個關於我正在修改的當前程序的問題。目前的計劃,我有:更復雜的排序:如何在一個類別內排序?

def extract_names(filename): 
    names = [] 
    f = open(filename, 'rU') 
    text = f.read() 

    yearmatch = re.search(r'Popularity\sin\s(\d\d\d\d)', text) 
    if not yearmatch: 
    sys.stderr.write('unavailable year\n') 
    sys.exit(1) 
    year = yearmatch.group(1) 
    names.append(year) 

    yeartuples = re.findall(r'<td>(\d+)</td><td>(\w+)</td>\<td>(\w+)</td>', text)#finds all patterns of date, boyname, and girlname, creates tuple) 

    rankednames = {} 
    for rank_tuple in yeartuples: 
    (rank, boyname, girlname) = rank_tuple 
    if boyname not in rankednames: 
     rankednames[boyname] = rank 
    if girlname not in rankednames: 
     rankednames[girlname] = rank 
    sorted_names = sorted(rankednames.keys(), key=lambda x: int(rankednames[x]), reverse = True) 
    for name in sorted_names: 
    names.append(name + " " + rankednames[name]) 
    return names[:20] 
#Boilerplate from this point** 

def main(): 

    args = sys.argv[1:] 

    if not args: 
    print 'usage: [--summaryfile] file [file ...]' 
    sys.exit(1) 

    summary = False 
    if args[0] == '--summaryfile': 
    summary = True 
    del args[0] 

    for filename in args: 
    names = extract_names(filename) 
    text = '\n'.join(names) 

    if summary: 
     outf = open(filename + '.summary', 'w') 
     outf.write(text + '\n') 
     outf.close() 
    else: 
     print text 

if __name__ == '__main__': 
    main() 

從關於在表中的某個今年最流行的嬰兒名的網站獲取信息,利用這些數據創建一個列表,並打印出來的寶寶名字的列表,以便從最低等級(1000)到最高等級(1)。我試圖做的修改應該是按字母順序排列所有的名字(第一個),但是在每個字母組中(所有a的組合,所有b的組等)。我想按降序對名稱進行排序在字母組中,所以以a開頭的排名最低的名字將是第一個顯示出來的名字。我最初能夠通過修改lambda函數來做到這一點,但是,我希望能夠實現這一點,而不需要lambda函數的修改。

+1

爲什麼你不能修改lambda函數? –

+0

[更復雜的排序:如何對數據進行分類並對分類中的數據進行排序? (Python的)](http://stackoverflow.com/questions/31373701/more-complex-sorting-how-to-cateorize-data-and-sort-the-data-within-categories) – Manhattan

回答

0

顯而易見的修復方法的確是修改您的lambda函數,以便它返回一個2元組(letter, rank)。既然你要排序的字母增加和降低等級,你要否定後者(而不是使用reverse=True):

sorted_names = sorted(rankednames, key=lambda x: (x[0], -int(rankednames[x]))) 

我能想到的唯一的選擇是兩次排序,先排名(反向),然後按首字母:

sorted_names = sorted(sorted(rankednames, 
          key=lambda x: int(rankednames[x]), 
          reverse=True), 
         key=lambda x: x[0]) 

這工作,因爲Python的Timsort是穩定的(它保留在他們輸入了相同的順序相同鍵的值)。這可能會比排序一次慢一點,但平均情況下它仍然是O(N log(N))