你正在做的terms = []
在函数的顶部,所以当然每次你递归调用该函数时,你都会这样做terms=[]
again.
最快的解决方案是编写一个简单的包装器:
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)——但这不是你想要依赖的东西。使用==
,它测试它们是否都表示相同的字符串,无论它们实际上是否是相同的对象。
Testing types因为身份经常有用一点,但通常仍然不是您想要的。事实上,您通常甚至不想测试类型equality。你通常不会有子类str
-但如果你这样做了,你可能会想把它们当作str
(因为这就是子类型化的全部意义)。对于您经常进行子类化的类型来说,这一点更为重要。
如果您不完全理解所有这些,简单的指导原则就是永远不要使用is
除非你知道你有充分的理由这样做。
所以,改变这个:
if i is not "THIS" and i is not "THAT":
……对此:
if i != "THIS" and i != "THAT":
或者,也许更好(如果您有四个字符串而不是两个要检查,那肯定更好),使用集合成员资格测试而不是and
将多个测试结合在一起:
if i not in {"THIS", "THAT"}:
同样,改变这个:
if type(i) is not str:
……对此:
if not isinstance(i, str):
但是,当我们在这里发挥全部功能时,为什么不使用闭包来消除全局呢?
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)
这不是我解决这个问题的方法(维姆的回答 https://stackoverflow.com/a/49247980/908494如果给出这个规范并告诉我用递归来解决它,我可能会这样做),但这具有保留现有设计的精神(以及大部分实现)的优点。