2013-10-11 167 views
0

爲CS1工作,我接近破解它,但是這部分代碼難倒我!該項目的目標是通過引用一個包含數千個名字的文件來創建任何給定年份前20名的名單。每個文件中的每一行都包含名稱,性別以及它發生的次數。這個文件是按性別分開的(所以女性的姓名按其出現的順序依次是男性姓名和後面的順序)。我已經獲得了代碼,其中每個條目都包含在列表中的一個類中(因此該列表是一長串內存條目)。這是我到目前爲止的代碼。Python:按類對象對列表進行排序

class entry(): 
    __slots__ = ('name' , 'sex' , 'occ') 

def mkEntry(name, sex, occ): 
    dat = entry() 
    dat.name = name 
    dat.sex = sex 
    dat.occ = occ 
    return dat 

##test = mkEntry('Mary', 'F', '7065') 
##print(test.name, test.sex, test.occ) 

def readFile(fileName): 
    fullset = [] 
    for line in open(fileName): 
     val = line.split(",") 
     sett = mkEntry(val[0] , val[1] , int(val[2])) 
     fullset.append(sett) 
    return fullset 

fullset = readFile("names/yob1880.txt") 
print(fullset) 

我想知道如果我能在這一點上做的是我可以通過sort()或其他功能的使用對此列表進行排序,但排序,它們的出現的列表(在每個條目dat.occ)等等在最終的結果中,我將有一個獨立於性別排序的列表,然後在那一點上,我可以列出列表中的第一個條目,因爲它們應該是我正在尋找的。是否可以像這樣對列表進行排序?

回答

1

是的,你可以使用sort()排序對象的列表。 sort()將函數作爲可選參數key。在進行比較之前,key函數應用於列表中的每個元素。例如,如果你想通過自己的絕對值排序整數列表,你可以做以下

>>> a = [-5, 4, 6, -2, 3, 1] 
>>> a.sort(key=abs) 
>>> a 
[1, -2, 3, 4, -5, 6] 

在你的情況,你需要自定義key將提取出現次數爲每個對象,例如

def get_occ(d): return d.occ 
fullset.sort(key=get_occ) 

(你也可以使用匿名函數:fullset.sort(key=lambda d: d.occ)來做到這一點)。然後你只需要從這個列表中提取前20個元素。

請注意,默認情況下,sort按升序返回元素,您可以操作它,例如, fullset.sort(key=get_occ, reverse=True)

+0

這工作完美!非常感謝^。^我們還沒有學習關鍵功能,但不幸的是,如果我的教授不接受D,我可能不得不找到一種全新的方式來做到這一點:但謝謝你給我看:) – BLU

0

這對列表進行排序按降序排列使用occ屬性:

fullset.sort(key=lambda x: x.occ, reverse=True) 
0

我覺得你只是要作爲排序依據每個對象的「OCC」屬性的值,對不對?您只需將key關鍵字參數用於Python提供的各種排序函數。例如

getocc = lambda entry: entry.occ 
sorted(fullset, key=getocc) 
# or, for in-place sorting 
fullset.sort(key=getocc) 

或許有人會認爲這是更Python使用operator.attrgetter,而不是一個自定義的λ:

import operator 
getocc = operator.attrgetter('occ') 
sorted(fullset, key=getocc) 

但聽起來好像列表是相當大的。如果您只想要列表中的前幾項,排序可能是一項不必要的昂貴操作。如果你想前三的說,你可以use a heap代替排序

min(fullset, key=getocc) # Same getocc as above 

:例如,如果你只希望第一值,你可以得到在O(n)的時間。

import heapq 
heapq.nsmallest(3, fullset, key=getocc) 

堆是用於獲取從列表排序的元素的切片而不排序整個列表的有用的數據結構。以上相當於sorted(fullset, key=getocc)[:3],但如果列表很大,則速度會更快。

希望很明顯你可以得到三個最大的heapq.nlargest和相同的論點。同樣,您可以反轉任何類型或將min替換爲max

+0

我真的不認爲'operator。* getter'工具特別是Pythonic,雖然人們似乎因爲某些原因喜歡它們。雖然有一點小小的性能上的好處,但它們非常脆弱:第二,你想做任何有趣的事情,結果你必須使用一個函數。 – DSM

+0

@DSM我不同意,我認爲他們的權力是在他們的專業化。如果他們是普通人,他們會因爲太TIMOWOWDI而變得不和諧。 – kojiro

0

你的意思是你想僅僅通過occ對列表進行排序?排序()有一個參數命名key,你可以這樣做:
fullset.sort(key=lambda x: x.occ)