2013-10-11 168 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)