我正在解决一个项目,我正在解析一个csv文件,该文件将包含教科书的各个部分和子部分,看起来像这样:
Chapter, Section, Lesson #this line shows how the book will be organized
Ch1Name, Secion1Name, Lesson1Name
Ch1Name, Secion2Name, Lesson1Name
Ch1Name, Secion2Name, Lesson2Name
我正在为每个部分创建Django模型对象,并且每个部分都有一个父属性,它是它所在的父节。我遇到了以这种方式浏览csv文件的方法父分配是正确的。任何有关如何入门的想法都会很棒。
答案 0 :(得分:1)
首先,希望您已经在使用csv
模块而不是尝试手动解析它。
其次,你的问题并不完全清楚,但听起来你正试图在阅读时从数据中建立一个简单的树结构。
那么,这样的事情呢?
with open('book.csv') as book:
chapters = collections.defaultdict(collections.defaultdict(list))
book.readline() # to skip the headers
for chapter_name, section_name, lesson_name in csv.reader(book):
chapters[chapter_name][section_name].append(lesson_name)
当然,假设你需要一个“关联树”-a dict
dict
s。更正常的线性树,如list
的{{1}},或“父指针”形式的隐式树,甚至更简单。
例如,假设你有这样定义的类:
list
你想要每个class Chapter(object):
def __init__(self, name):
self.name = name
class Section(object):
def __init__(self, chapter, name):
self.chapter = chapter
self.name = name
class Lesson(object):
def __init__(self, section, name):
self.section = section
self.name = name
,将名称映射到对象。所以:
dict
现在,您可以选择随机课程,并打印其章节和部分:
with open('book.csv') as book:
chapters, sections, lessons = {}, {}, {}
book.readline() # to skip the headers
for chapter_name, section_name, lesson_name in csv.reader(book):
chapter = chapters.setdefault(chapter_name, Chapter(chapter_name))
section = sections.setdefault(section_name, Section(chapter, section_name))
lesson = lessons.setdefault(lesson_name, Lesson(section, lesson_name))
要记住的最后一件事:在此示例中,父引用不会导致任何循环引用,因为父项没有对其子项的引用。但是,如果你需要它呢?
lesson = random.choice(lessons.values())
print('Chapter {}, Section {}: Lesson {}'.format(lesson.section.chapter.name,
lesson.section.name, lesson.name))
到目前为止,这么好......但是当你完成所有这些对象后会发生什么?它们具有循环引用,这可能导致垃圾收集问题。这不是不可克服的问题,但它确实意味着在大多数实现中不会快速收集对象。例如,在CPython中,一旦最后一个引用超出范围,通常会收集东西 - 但是如果你有循环引用,那么从未发生,所以在循环检测器的下一次传递之前不会收集任何东西。对此的解决方案是使用weakref
作为父指针(或子集的class Chapter(object):
def __init__(self, name):
self.name = name
self.sections = {}
class Section(object):
def __init__(self, chapter, name):
self.chapter = chapter
self.name = name
self.lessons = {}
# ...
chapter = chapters.setdefault(chapter_name, Chapter(chapter_name))
section = sections.setdefault(section_name, Section(chapter, section_name))
chapters[section_name] = section
)。