0

正在为 CS1 做一个项目,我快要破解它了,但这部分代码让我难住了!该项目的目标是通过引用一个包含数千个名字的文件来创建任何给定年份的前 20 个名字的列表。每个文件中的每一行都包含名称、性别和出现的次数。该文件按性别分隔(因此女性姓名按出现顺序排列,男性姓名按出现顺序排列)。我已经得到了代码,每个条目都包含在列表中的一个类中(所以这个列表是一长串内存条目)。这是我到目前为止的代码。

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)对列表进行排序,所以最终结果我会得到一个独立于性别排序的列表,然后我可以打印列表中的第一个条目,因为它们应该是我正在寻找的。是否可以像这样对列表进行排序?

4

4 回答 4

2

是的,您可以使用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)

于 2013-10-11T02:24:03.620 回答
0

这使用occ属性按降序对列表进行排序:

fullset.sort(key=lambda x: x.occ, reverse=True)
于 2013-10-11T02:21:34.650 回答
0

我认为您只想对每个对象的“occ”属性的值进行排序,对吗?您只需要对keyPython 可用的各种排序函数中的任何一个使用关键字参数。例如

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

或者也许有些人可能认为使用它operator.attrgetter而不是自定义 lambda 更符合 Python 风格:

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

但听起来这个列表相当大。如果您只想要列表中的前几个条目,则排序可能是一项不必要的昂贵操作。例如,如果你只想要第一个值,你可以在 O(N) 时间内得到它:

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

如果你想要前三个,比如说,你可以使用堆而不是排序。

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

堆是一种有用的数据结构,用于从列表中获取有序元素的切片,而无需对整个列表进行排序。以上等价于sorted(fullset, key=getocc)[:3],但如果列表很大,则速度更快。

希望很明显,您可以使用heapq.nlargest相同的参数获得三个最大的参数。同样,您可以反转任何排序或替换minmax.

于 2013-10-11T02:21:56.777 回答
0

您的意思是您只想按 occ 对列表进行排序?sort() 有一个名为 的参数key,你可以这样做:
fullset.sort(key=lambda x: x.occ)

于 2013-10-11T02:22:11.227 回答