Как мне создать список или установить объект в классе в Python? - PullRequest
2 голосов
/ 19 февраля 2010

Для моего проекта роль лектора (определяемого как класс) состоит в том, чтобы предлагать проекты студентам. Сам проект тоже класс. У меня есть несколько глобальных словарей, снабженных уникальными числовыми идентификаторами для лекторов и проектов, которые отображаются на объекты.

Таким образом, для словаря "лекторов" (в настоящее время):

lecturer[id] = Lecturer(lec_name, lec_id, max_students)

В настоящее время я читаю в текстовом файле с пробелами с разделителями, который был сгенерирован из базы данных. У меня нет прямого доступа к базе данных, поэтому я мало что могу сказать о том, как файл отформатирован. Вот вымышленный фрагмент, который показывает, как структурирован текстовый файл. Прошу прощения за нежность.

0001 001 "Miyamoto, S." "Even Newer Super Mario Bros"
0002 001 "Miyamoto, S." "Legend of Zelda: Skies of Hyrule"
0003 002 "Molyneux, P." "Project Milo"
0004 002 "Molyneux, P." "Fable III"
0005 003 "Blow, J." "Ponytail"

Структура каждой строки в основном proj_id, lec_id, lec_name, proj_name.

Теперь я сейчас читаю соответствующие данные в соответствующие объекты. Таким образом, proj_id хранится в class Project, тогда как lec_name является объектом class Lecturer и др. Классы Lecturer и Project в настоящее время не связаны.

Однако, поскольку я читаю в каждой строке текстового файла, для этой строки я хочу прочитать проект, предложенный лектором, в класс Lecturer; Я уже читаю proj_id в Project классе. Я хотел бы создать объект в Lecturer с именем offered_proj, который должен быть набором или списком проектов, предлагаемых этим лектором. Таким образом, всякий раз, когда для строки я читаю в новом проекте под тем же lec_id, offered_proj будет обновляться вместе с этим проектом. Если бы я хотел получить список проектов, предлагаемых лектором, я бы в идеале просто хотел бы использовать print lecturers[lec_id].offered_proj.

Мой Python не великолепен, и я был бы признателен, если бы кто-нибудь показал мне способ сделать это. Я не уверен, лучше ли это как набор или список.

Update

После совета от Алекс Мартелли и Нечетное мышление Я вернулся и внес некоторые изменения и попытался напечатать результаты.

Вот фрагмент кода:

for line in csv_file:
    proj_id = int(line[0])
    lec_id = int(line[1])
    lec_name = line[2]
    proj_name = line[3]
    projects[proj_id] = Project(proj_id, proj_name)
    lecturers[lec_id] = Lecturer(lec_id, lec_name)
    if lec_id in lecturers.keys():
        lecturers[lec_id].offered_proj.add(proj_id)
    print lec_id, lecturers[lec_id].offered_proj

В строке print lecturers[lec_id].offered_proj выводится следующий вывод:

001 set([0001])
001 set([0002])
002 set([0003])
002 set([0004])
003 set([0005])

По сути, создается впечатление, что набор переписан или что-то в этом роде. Поэтому, если я попытаюсь напечатать для конкретного лектора print lec_id, lecturers[001].offered_proj, все, что я получу, это последний прочитанный proj_id.

Ответы [ 3 ]

4 голосов
/ 19 февраля 2010

set лучше, так как вы не заботитесь о заказе и не имеете дубликатов.

Вы можете легко проанализировать файл с помощью модуля csv delimiter из ' ').

Как только у вас есть lec_name, вы должны проверить, знает ли уже этот лектор; для этого сохраните словарь от lec_name до объектов лектора (это еще одна ссылка на тот же объект лектора, на который вы также ссылаетесь из словаря lecturer). Найдя lec_name, которого нет в этом словаре, вы узнаете, что это лектор, которого раньше не видели, поэтому создайте новый объект лектора (и вставьте его в оба слова) только в этом случае с пустым набором предлагаемых курсов. Наконец, просто .add курс к текущему преподавателю offered_proj. Это действительно довольно плавный поток.

Вы пытались реализовать этот поток? Если да, то какие у вас были проблемы? Можете ли вы показать нам соответствующий код - максимум дюжина строк или около того?

Редактировать : поскольку ОП уже опубликовал код, я могу обнаружить ошибку - она ​​здесь:

lecturers[lec_id] = Lecturer(lec_id, lec_name)
if lec_id in lecturers.keys():
    lecturers[lec_id].offered_proj.add(proj_id)

это безоговорочно создание нового объекта лектора (растоптавшего старый в диктовке lecturers, если есть), поэтому, конечно, предыдущий набор будет отброшен. Вот код, который вам нужен: сначала проверьте и создайте только при необходимости! (также, небольшая ошибка, не проверка in....keys(), это ужасно неэффективно - просто проверьте наличие в диктанте). Следующим образом:

if lec_id in lecturers:
    thelec = lecturers[lec_id]
else:
    thelec = lecturers[lec_id] = Lecturer(lec_id, lec_name)
thelec.offered_proj.add(proj_id)

Вы можете выразить это несколькими различными способами, но я надеюсь, что это достаточно ясно. Просто для полноты я обычно формулирую это (чтобы избежать двух поисков в словаре) следующим образом:

thelec = lecturers.get(lec_id)
if thelec is None:
    thelec = lecturers[lec_id] = Lecturer(lec_id, lec_name)
thelec.offered_proj.add(proj_id)
1 голос
/ 19 февраля 2010

Наборы полезны, когда вы хотите гарантировать, что у вас есть только один экземпляр каждого предмета. Они также быстрее, чем список, вычисляют, присутствует ли элемент в коллекции.

Списки добавляются быстрее, а также имеют порядок.

Звучит так, будто вы хотели бы сет. Похоже, вы уже очень близки.

в лекторе. init , добавьте строку:

self.offered_proj = set()

Это создаст пустой набор.

Когда вы читаете в проекте, вы можете просто добавить к этому набору:

lecturer.offered_proj.add(project)

И вы можете печатать, как вы предлагаете (хотя вам может понравиться).

0 голосов
/ 19 февраля 2010

Спасибо за помощь Alex и Oddthinking ! Я думаю, я понял, что происходит:

Я изменил фрагмент кода, который добавил к вопросу. По сути, каждый раз, когда он читает строку, я думаю, что он воссоздает объект лектора. Таким образом, я вставил еще один оператор if, который проверяет, существует ли lec_id в словаре. Если это так, тогда он пропускает создание объекта и просто переходит к добавлению проектов в набор offered_proj.

Я сделал следующее изменение:

if not lec_id in lecturers.keys():
    projects[proj_id] = Project(proj_id, proj_name)
lecturers[lec_id] = Lecturer(lec_id, lec_name)
lecturers[lec_id].offered_proj.add(proj_id)

Я только недавно обнаружил концепцию, стоящую за if not благодаря моему другу Самиру.

Теперь я получаю следующий вывод:

001 set([0001])
001 set([0001, 0002])
002 set([0003])
002 set([0003, 0004])
003 set([0005])

Если я print для выбранного lec_id, я получаю полностью обновленный набор. Glee.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...