recursive function for extract elements from deep nested lists/tuples(从深层嵌套列表/元组中提取元素的递归函数)
问题描述
我想编写一个从深层嵌套的元组和列表中提取元素的函数,比如我有这样的东西
I want to write a function that extracts elements from deep nested tuples and lists, say I have something like this
l = ('THIS', [('THAT', ['a', 'b']), 'c', ('THAT', ['d', 'e', 'f'])])
我想要一个没有这个"和那个"的平面列表:
And I want a flat list without 'THIS' and 'THAT':
list = ['a', 'b', 'c', 'd', 'e', 'f']
这是我目前所拥有的:
def extract(List):
global terms
terms = []
for i in word:
if type(i) is not str:
extract(i)
else:
if i is not "THIS" and i is not "THAT":
terms.append(i)
return terms
但我一直得到 list = ['d', 'e', 'f']
,看起来 terms = []
在循环后再次设置到 'c'
.
But I keep getting list = ['d', 'e', 'f']
, it looks like the terms = []
is set again after looping to 'c'
.
推荐答案
你是在函数顶部做terms = []
,所以当然每次递归调用函数时,你又在这样做了terms=[]
.
You're doing terms = []
at the top of the function, so of course every time you recursively call the function, you're doing that terms=[]
again.
最快的解决方案是编写一个简单的包装器:
The quickest solution is to write a simple wrapper:
def _extract(List):
global terms
for i in word:
if type(i) is not str:
_extract(i)
else:
if i is not "THIS" and i is not "THAT":
terms.append(i)
return terms
def extract(List):
global terms
terms = []
return _extract(List)
<小时>
还有一点:你不应该使用 is
来测试字符串是否相等(除非在非常非常特殊的情况下).这将测试它们内存中的相同字符串对象.它会碰巧在这里工作,至少在 CPython 中(因为 "THIS"
两个字符串都是同一个模块中的常量——即使它们不是,他们也会得到 intern
ed)——但这不是你想要依赖的东西.使用 ==
,它测试它们是否表示相同的字符串,无论它们是否实际上是相同的对象.
One more thing: You shouldn't use is
to test for string equality (except in very, very special cases). That tests that they're the same string object in memory. It will happen to work here, at least in CPython (because both "THIS"
strings are constants in the same module—and even if they weren't, they'd get intern
ed)—but that's not something you want to rely on. Use ==
, which tests that they both mean the same string, whether or not they're actually the identical object.
测试类型的身份更有用一点,但通常仍然不是您想要的.事实上,您通常甚至不想测试类型是否相等.您通常不会拥有 str
的子类——但如果有,您可能希望将它们视为 str
(因为这是子类型化的全部意义所在).这对于您更频繁地进行子类化的类型更为重要.
Testing types for identity is useful a little more often, but still not usually what you want. In fact, you usually don't even want to test types for equality. You don't often have subclasses of str
—but if you did, you'd probably want to treat them as str
(since that's the whole point of subtyping). And this is even more important for types that you do subclass from more often.
如果您不完全理解所有这些,简单的指导原则是永远不要使用 is
,除非您知道自己有充分的理由这样做.
If you don't completely understand all of that, the simple guideline is to just never use is
unless you know you have a good reason to.
所以,改变这个:
if i is not "THIS" and i is not "THAT":
…到这个:
if i != "THIS" and i != "THAT":
或者,也许更好(如果你有四个字符串来检查而不是两个,肯定会更好),使用集合成员测试而不是和
将多个测试放在一起:
Or, maybe even better (definitely better if you had, say, four strings to check instead of two), use a set membership test instead of and
ing together multiple tests:
if i not in {"THIS", "THAT"}:
同样,改变这个:
if type(i) is not str:
…到这个:
if not isinstance(i, str):
<小时>
但是,虽然我们在这里都是函数式的,为什么不使用闭包来消除全局呢?
But while we're being all functional here, why not use a closure to eliminate the global?
def extract(List)
terms = []
def _extract(List):
nonlocal terms
for i in word:
if not isinstance(i, str):
_extract(i)
else:
if i not in {"THIS", "THAT"}:
terms.append(i)
return terms
return _extract(List)
这不是我解决这个问题的方式(wim 的回答可能是我会做的,如果给出这个规范并被告知用递归解决它),但这具有保留现有设计(以及大部分实现)的精神的优点.
This isn't the way I'd solve this problem (wim's answer is probably what I'd do if given this spec and told to solve it with recursion), but this has the virtue of preserving the spirit of (and most of the implementation of) your existing design.
这篇关于从深层嵌套列表/元组中提取元素的递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从深层嵌套列表/元组中提取元素的递归函数
基础教程推荐
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 筛选NumPy数组 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01