CSV解析

2024-09-21 00:20:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个项目中遇到了问题,在这个项目中,我正在解析一个csv文件,该文件将包含教科书的部分和子部分,如下所示:

Chapter, Section, Lesson  #this line shows how the book will be organized
Ch1Name, Secion1Name, Lesson1Name
Ch1Name, Secion2Name, Lesson1Name
Ch1Name, Secion2Name, Lesson2Name

我正在为每个节创建Django模型对象,每个节都有一个parent属性,它就是它所在的父节。我很难想出一种方法来通过csv文件,这样的方式,家长分配是正确的。任何关于如何开始的想法都会很好。你知道吗


Tags: 文件csvthe项目linesectionthisshows
1条回答
网友
1楼 · 发布于 2024-09-21 00:20:21

首先,希望您已经在使用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)

当然,这是假设你想要一个“关联树”——一个dictdict树。一个更普通的线性树,比如listlist树,或者一个“父指针”形式的隐式树,更简单。你知道吗

例如,假设您有这样定义的类:

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

最后要记住的一点:在本例中,父引用不会导致任何循环引用,因为父引用没有对其子引用。但如果你需要呢?你知道吗

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

到目前为止,还不错…但是当你处理完所有这些物体之后会发生什么呢?它们具有循环引用,这可能会导致垃圾回收问题。这不是不可克服的问题,但它确实意味着在大多数实现中对象不会被快速收集。例如,在CPython中,当最后一个引用超出范围时,通常会立即收集内容,但是如果您有循环引用,则不会发生这种情况,因此在循环检测器的下一个过程之前不会收集任何内容。解决方法是使用^{}作为父指针(或子指针的weakref集合)。你知道吗

相关问题 更多 >

    热门问题