I have a dataclass like this:
class chapter:
title: str
text: str = ''
chapter: List['chapter'] = field(default_factory=list)
removed: bool = False
Say there is a list object that contains instances of that dataclass with these values:
content = [
chapter(
'chapter 1',
chapter=[
chapter('subchapter 1', "Lorem ipsum dolor"),
chapter('subchapter 2', "Nullam a ligula")
]
),
chapter(
'chapter 2',
chapter=[
chapter('subchapter 1', "Fusce eget commodo augue"),
chapter('subchapter 2', "Pellentesque pretium")
]
),
chapter(
'chapter 3', removed=True
),
chapter(
'chapter 3',
chapter=[
chapter('subchapter 1', "Duis sit amet tempus lectus"),
]
),
]
Let's say I want to recursively set values removed
to True for a selected chapter with an index 0, and in all subchapters of the chapter. How can I do that? Any suggestions are appreciated.
CodePudding user response:
The naming in your code is a bit confusing - you should name the class Chapter
instead of chapter
and the list chapter
should probably be called chapters
.
Having said that, this appears to be what you want:
from typing import List
from dataclasses import dataclass, field
@dataclass
class Chapter:
title: str
text: str = ''
chapters: List['Chapter'] = field(default_factory=list)
removed: bool = False
def remove(self):
self.removed = True
for chapter in self.chapters:
chapter.remove()
content = [
Chapter(
title='chapter 1',
chapters=[
Chapter('subchapter 1', "Lorem ipsum dolor"),
Chapter('subchapter 2', "Nullam a ligula")
]
),
Chapter(
'chapter 2',
chapters=[
Chapter('subchapter 1', "Fusce eget commodo augue"),
Chapter('subchapter 2', "Pellentesque pretium")
]
),
Chapter(
'chapter 3', removed=True
),
Chapter(
'chapter 3',
chapters=[
Chapter('subchapter 1', "Duis sit amet tempus lectus"),
]
),
]
content[0].remove()
print(content)
Calling .remove()
on a chapter sets .removed
to True
, but also calls .remove()
on any of its subchapters, recursively setting .removed
on all of them and their subchapters.
CodePudding user response:
Use a recursive function:
def remove_recursive(chapter_instance: chapter) -> None:
chapter_instance.removed = True
for c in chapter_instance.chapter:
remove_recursive(c)
Note that conventionally you would call your class Chapter
, and then could use the name chapter
to refer to an instance of that class (instead of chapter_instance
as I've very awkwardly done here.)