如何使用 yield 和 generator 函数将递归函数的输出保存到项目列表
How to save the output of recursive function to list of items using yield and generator functions
我有以下来自 link 的 XML 文件作为示例:
我有以下打印输出的递归函数:
import xml.etree.ElementTree as ET
def perf_func(elem, func, level=0):
func(elem,level)
for child in elem.getchildren():
perf_func(child, func, level+1)
def print_level(elem,level):
print('-'*level+elem.tag)
elemList = ['description', 'episodes', 'movie', 'collection', 'stars', 'rating', 'year', 'type', 'format']
xmlTree = ET.parse('XML_file.xml')
下面一行打印结果:
perf_func(xmlTree.getroot(), print_level)
输出:
collection
-movie
--type
--format
--year
--rating
--stars
--description
-movie
--type
--format
--year
--rating
--stars
--description
-movie
--type
我需要将输出保存到如下所示的项目列表中。
hierarchy = [collection, -movie, --format, --year, --rating, ... ]
所以尝试了下面的修改。但无法获得列表的结果。
import xml.etree.ElementTree as ET
def perf_func(elem, func, level=0):
func(elem,level)
for child in elem.getchildren():
yield from perf_func(child, func, level+1)
def print_level(elem,level):
print ('-'*level+elem.tag)
我试图修改 print_level() 函数以提供一些可返回的输出而不是打印它,但不知道该怎么做。
perf_func(xmlTree.getroot(), print_level)
<generator object perf_func at 0x000001F6432BD2C8>
将生成器更改为 list 给我相同的输出
list(perf_func(xmlTree.getroot(), print_level))
我在其他链接中查看了类似的问题,但不太理解。
使用 yield from
但从未 yield
任何值的函数没有意义。生成器需要在某个时候填充数据才能执行任何操作。
def perf_func(elem):
yield elem
for child in elem.getchildren():
yield from perf_func(child)
您可以使用 yield func(elem, level)
,但是将函数传递给生成器是一种有点奇怪的模式,它颠倒了责任。生成器的典型模式是懒惰地发出数据,让调用者对每个内联项应用任意处理,例如:
def traverse(elem, level=0):
yield elem, level
for child in elem.getchildren():
yield from traverse(child, level + 1)
for elem, level in traverse(xmlTree.getroot()):
print("-" * level + elem.tag) # or whatever else you want to do
在 Python 3.9 中,elem.getchildren
是 removed,所以这里是对我有用的代码:
import xml.etree.ElementTree as ET
def traverse(elem, level=0):
yield elem, level
for child in elem:
yield from traverse(child, level + 1)
for elem, level in traverse(ET.parse("country_data.xml").getroot()):
print(" " * level + elem.tag) # or whatever else you want to do
我有以下来自 link 的 XML 文件作为示例:
我有以下打印输出的递归函数:
import xml.etree.ElementTree as ET
def perf_func(elem, func, level=0):
func(elem,level)
for child in elem.getchildren():
perf_func(child, func, level+1)
def print_level(elem,level):
print('-'*level+elem.tag)
elemList = ['description', 'episodes', 'movie', 'collection', 'stars', 'rating', 'year', 'type', 'format']
xmlTree = ET.parse('XML_file.xml')
下面一行打印结果:
perf_func(xmlTree.getroot(), print_level)
输出:
collection
-movie
--type
--format
--year
--rating
--stars
--description
-movie
--type
--format
--year
--rating
--stars
--description
-movie
--type
我需要将输出保存到如下所示的项目列表中。
hierarchy = [collection, -movie, --format, --year, --rating, ... ]
所以尝试了下面的修改。但无法获得列表的结果。
import xml.etree.ElementTree as ET
def perf_func(elem, func, level=0):
func(elem,level)
for child in elem.getchildren():
yield from perf_func(child, func, level+1)
def print_level(elem,level):
print ('-'*level+elem.tag)
我试图修改 print_level() 函数以提供一些可返回的输出而不是打印它,但不知道该怎么做。
perf_func(xmlTree.getroot(), print_level)
<generator object perf_func at 0x000001F6432BD2C8>
将生成器更改为 list 给我相同的输出
list(perf_func(xmlTree.getroot(), print_level))
我在其他链接中查看了类似的问题,但不太理解。
使用 yield from
但从未 yield
任何值的函数没有意义。生成器需要在某个时候填充数据才能执行任何操作。
def perf_func(elem):
yield elem
for child in elem.getchildren():
yield from perf_func(child)
您可以使用 yield func(elem, level)
,但是将函数传递给生成器是一种有点奇怪的模式,它颠倒了责任。生成器的典型模式是懒惰地发出数据,让调用者对每个内联项应用任意处理,例如:
def traverse(elem, level=0):
yield elem, level
for child in elem.getchildren():
yield from traverse(child, level + 1)
for elem, level in traverse(xmlTree.getroot()):
print("-" * level + elem.tag) # or whatever else you want to do
在 Python 3.9 中,elem.getchildren
是 removed,所以这里是对我有用的代码:
import xml.etree.ElementTree as ET
def traverse(elem, level=0):
yield elem, level
for child in elem:
yield from traverse(child, level + 1)
for elem, level in traverse(ET.parse("country_data.xml").getroot()):
print(" " * level + elem.tag) # or whatever else you want to do