递归函数,用于从深层嵌套列表/元组中提取元素 [英] recursive function for extract elements from deep nested lists/tuples

查看:88
本文介绍了递归函数,用于从深层嵌套列表/元组中提取元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个从深层嵌套元组和列表中提取元素的函数,说我有类似的东西

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'])])

我想要一个没有'THIS'和'THAT'的简单列表:

And I want a flat list without 'THIS' and 'THAT':

list = ['a', 'b', 'c', 'd', 'e', 'f']

这是我到目前为止所拥有的:

Here's what I have so far:

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)-但这不是您想要的依靠.使用==来测试它们是否都代表相同的字符串,无论它们实际上是否是相同的对象.


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 interned)—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":

或者,甚至更好(如果要检查四个字符串而不是两个,绝对更好),请使用集合成员资格测试,而不是and将多个测试放在一起:

Or, maybe even better (definitely better if you had, say, four strings to check instead of two), use a set membership test instead of anding 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.

这篇关于递归函数,用于从深层嵌套列表/元组中提取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆