2013-10-11 3 views
0

Я смущен о классах в python. Я не хочу, чтобы кто-то записывал исходный код, но предлагал методы его выполнения. Прямо сейчас у меня есть следующий код ...Объекты/классы/списки 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') 

Этот класс только определяет, какие объекты я должен сделать. Целью проекта является создание объектов и создание списков, основанных на этих объектах. Моя главная функция возвращает список, содержащий несколько элементов, которые выглядят следующим образом:

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

Эти элементы имеют имя в lst[0], гендерно M или F в [1] и событие в [3]. Я пытаюсь найти топ-20 кандидатов мужского и женского пола и распечатать их.

Goal- Должна быть функция, которая создает запись имени, т. Е. MkEntry. Он должен быть передал соответствующую информацию, построил новый объект, заполнил поля и вернул его.

+0

И что конкретно у вас есть вопрос? – jwodder

+0

Я пытаюсь заполнить объекты и создать список с верхними 20 M и верхними 20 F встречами. – steve

+0

Это не вопрос. Что именно с задачей вы сталкиваетесь? – jwodder

ответ

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)] 

Вы можете получить доступ к различные значения либо по индексу (как list или tuple) или по названию атрибута (например, пользовательский объект):

>>> jon = lst[0] 
>>> print(jon[0]) 
jon 
>>> print(jon.gender) 
M 
0

В своем классе, добавьте __init__ метод, например:

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

Теперь вам не нужен отдельный «сделать» метод; просто вызовите сам класс как конструктор:

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

И это все, что нужно.

Если вы действительно хотите функцию mkEntry в любом случае, это будет просто один лайнер: return Names(etc.)

0

Я знаю, что вы сказали, не выписывать код, но это просто легче объяснить это так. Вам не нужно использовать слоты - они предназначены для специализированной оптимизации (и если вы не знаете, что это такое, вам это не нужно).

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() 

Я использовал несколько возможностей здесь может выглядеть немного страшно, но они достаточно легко, как только вы привыкнете к ним (и вы увидите их все более питона кода). Перечисление списков дает нам простой способ фильтрации нашего списка людей в полы. lambda дает анонимную функцию. Синтаксис [: 20] говорит, дайте мне первые 20 элементов этого списка - обратитесь к разрезанию списка.

Ваш случай довольно прост, и вам, вероятно, даже не нужен класс/объекты, но он должен дать вам представление о том, как вы их используете. В python также есть библиотека чтения csv, которая поможет вам, если csvs будут более сложными (поля с кавычками и т. Д.).