efs*_*see 2 python recursion nested python-3.x
我想编写一个从深层嵌套元组和列表中提取元素的函数,比方说我有这样的东西
l = ('THIS', [('THAT', ['a', 'b']), 'c', ('THAT', ['d', 'e', 'f'])])
Run Code Online (Sandbox Code Playgroud)
我想要一个没有'THIS'和'THAT'的平面列表:
list = ['a', 'b', 'c', 'd', 'e', 'f']
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的:
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
Run Code Online (Sandbox Code Playgroud)
但我一直在接受list = ['d', 'e', 'f'],看起来terms = []循环后再次设置'c'.
你正在做terms = []函数的顶部,所以当然每次递归调用函数时,你都会terms=[]再次这样做.
最快的解决方案是编写一个简单的包装器:
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)
Run Code Online (Sandbox Code Playgroud)
还有一件事:你不应该is用来测试字符串相等性(除非是非常非常特殊的情况).这测试它们在内存中是相同的字符串对象.它会发生在这里,至少在CPython中(因为两个"THIS"字符串都是同一个模块中的常量 - 即使它们不是,它们也会被intern编辑) - 但这不是你想要依赖的东西.使用==,测试它们是否意味着相同的字符串,无论它们是否实际上是相同的对象.
测试身份类型更常用,但通常不是你想要的.实际上,您通常甚至不想测试类型是否相等.你通常不会有子类str- 但如果你这样做了,你可能想把它们视为str(因为这是子类型的全部要点).对于你经常进行子类化的类型来说,这一点更为重要.
如果你还没有完全理解所有这些,那么简单的指导就是永远不要使用,is除非你知道你有充分的理由.
所以,改变这个:
if i is not "THIS" and i is not "THAT":
Run Code Online (Sandbox Code Playgroud)
......对此:
if i != "THIS" and i != "THAT":
Run Code Online (Sandbox Code Playgroud)
或者,甚至可能更好(如果你有四个字符串要检查而不是两个,那肯定会更好),使用集合成员资格测试而不是and多个测试:
if i not in {"THIS", "THAT"}:
Run Code Online (Sandbox Code Playgroud)
同样,改变这个:
if type(i) is not str:
Run Code Online (Sandbox Code Playgroud)
......对此:
if not isinstance(i, str):
Run Code Online (Sandbox Code Playgroud)
但是,虽然我们在这里全部运作,为什么不使用闭包来消除全局?
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)
Run Code Online (Sandbox Code Playgroud)
这不是我解决这个问题的方法(如果给出这个规范并告诉我用递归来解决它,那么我的答案可能是我要做的),但这有保留(和大部分的)精神的优点.实施)您现有的设计.