0

我对python中的类感到困惑。我不希望任何人写下原始代码,但建议这样做的方法。现在我有以下代码......

def main():
    lst = []
    filename = 'yob' + input('Enter year: ') + '.txt'
    for line in open(filename):
        line = line.strip()
        lst.append(line.split(',')

这段代码的作用是输入基于年份的文件。该程序放置在一个文件夹中,其中包含一堆不同年份的文本文件。然后,我做了一个类...

class Names():
    __slots__ = ('Name', 'Gender', 'Occurences')

这个类只定义了我应该制作的对象。该项目的目标是构建对象并基于这些对象创建列表。我的 main 函数返回一个列表,其中包含如下所示的几个元素:

[[jon, M, 190203], ...]

这些元素具有名称 in lst[0]、性别MFin[1]和出现 in [3]。我正在尝试找到前 20 名男性和女性候选人并将其打印出来。

目标 - 应该有一个创建名称条目的函数,即 mkEntry。它应该被传递适当的信息,构建一个新对象,填充字段,然后返回它。

4

3 回答 3

0

I know you said not to write out the code but it's just easier to explain it this way. You don't need to use slots - they're for a specialised optimisation purpose (and if you don't know what it is, you don't need it).

class Person(object):
    def __init__(self, name, gender, occurrences):
        self.name = name
        self.gender = gender
        self.occurrences = occurrences


def main():
    # read in the csv to create a list of Person objects
    people = []
    filename = 'yob' + input('Enter year: ') + '.txt'
    for line in open(filename):
        line = line.strip()
        fields = line.split(',')
        p = Person(fields[0], fields[1], int(fields[2]))
        people.append(p)

    # split into genders
    p_m = [p for p in people if p.gender == 'M']
    p_f = [p for p in people if p.gender == 'F']

    # sort each by occurrences descending
    p_m = sorted(p_m, key=lambda x: -x.occurrences)
    p_f = sorted(p_f, key=lambda x: -x.occurrences)

    # print out the first 20 of each
    for p in p_m[:20]:
        print p.name, p.gender, p.occurrences
    for p in p_f[:20]:
        print p.name, p.gender, p.occurrences

if __name__ == '__main__':
    main()

I've used a couple of features here that might look a little scary, but they're easy enough once you get used to them (and you'll see them all over python code). List comprehensions give us an easy way of filtering our list of people into genders. lambda gives you an anonymous function. The [:20] syntax says, give me the first 20 elements of this list - refer to list slicing.

Your case is quite simple and you probably don't even really need the class / objects but it should give you an idea of how you use them. There's also a csv reading library in python that will help you out if the csvs are more complex (quoted fields etc).

于 2013-10-11T23:18:26.427 回答
0

在您的类中,添加一个__init__方法,如下所示:

def __init__(self, name, gender, occurrences):
    self.Name = name
    # etc.

现在您不需要单独的“make”方法;只需将类本身称为构造函数:

myname = Names(lst[0], etc.)

这就是它的全部。

如果你真的想要一个 mkEntry 函数,它只是一个单行:return Names(etc.)

于 2013-10-11T22:52:20.943 回答
0

如果你想要的只是一个方便的容器类来保存你的数据,我建议使用模块中的namedtuple类型工厂collections,它就是为此而设计的。您可能还应该使用该csv模块来处理读取文件。Python自带“含电池”,学习使用标准库吧!

from collections import namedtuple
import csv

Person = namedtuple('Person', ('name', 'gender', 'occurences')) # create our type

def main():
    filename = 'yob' + input('Enter year: ') + '.txt'
    with open(filename, newlines="") as f: # parameters differ a bit in Python 2
        reader = csv.reader(f) # the reader handles splitting the lines for you
        lst = [Person(*row) for row in reader]

注意:如果您使用的是 Python 2,则该csv模块需要您以open二进制模式(带有第二个参数'rb')而不是使用newlines参数来访问文件。

如果您的文件只有您在示例输出中使用的一个人,您将获得一个包含一个Person对象的列表:

>>> print(lst)    
[Person(name='jon', gender='M', occurences=190203)]

您可以通过索引(如 alisttuple)或属性名称(如自定义对象)访问各种值:

>>> jon = lst[0]
>>> print(jon[0])
jon
>>> print(jon.gender)
M
于 2013-10-11T23:52:08.800 回答