【问题标题】:How would I Recursively get unique items out of nested lists?我将如何递归地从嵌套列表中获取唯一项?
【发布时间】:2020-06-23 04:52:35
【问题描述】:

所以,我是递归的初学者。

我必须回答一个问题,在该问题中我定义了一个函数,该函数将由数字或字母组成的嵌套列表作为参数,并且我必须返回一个包含所有唯一值的字典。 (我必须递归解决这个问题)

def extract_unique_elements(lists):
    if isinstance(lists, int):
        return {lists}

    for i in set(lists):
        return extract_unique_elements({i})

很明显,这甚至还没有接近工作。如果是的话;但是,当传递一个嵌套列表时,它会返回如下:

>>> extract_unique_elements([1,[2,1,[5,5,[2]]]]) 
{1,2,5}

>>> extract_unique_elements([a,[a,b,[c,b,[e]]]])
{a,b,c,e}

【问题讨论】:

    标签: python-3.x list recursion nested nested-lists


    【解决方案1】:

    这是您可以做到的一种方式:

    result = set()
    lists = [1,[2,1,[5,5,[2]]]]
    
    def extract_unique_elements(lists, result):
        if isinstance(lists, list):
            for item in lists:
                extract_unique_elements(item, result)
    
        else:
            result.add(lists)
    
    extract_unique_elements(lists, result)
    
    result
    # {1, 2, 5}
    

    【讨论】:

    • 该函数只能接受一个由嵌套列表组成的参数,并且还必须处理字母
    • 修改此代码以在递归链的开头创建一个新的result 集并不难。只需给它一个标记默认值,如None 并在开始时检查它。与在每个级别上构建单独的结果集并需要将递归结果中的数据复制到其中相比,仅使用一个通过递归调用传递的结果集效率更高。
    【解决方案2】:

    你可以使用:

    def extract_unique_elements(lists):
        if isinstance(lists, int):
            return {lists}
    
        values = set()
        for i in lists:
            values.update(extract_unique_elements(i))
    
        return values
    

    或:

    def extract_unique_elements(lists):
        if isinstance(lists, int):
            return {lists}
    
        return {i for e in lists for i in extract_unique_elements(e)}
    

    测试:

    extract_unique_elements([1,[2,1,[5,5,[2]]]])
    # {1, 2, 5}
    

    如果您想要更紧凑的版本,您可以使用:

    def extract_unique_elements(lists):
        return {i for e in lists  for i in ([e] if isinstance(e, int) else extract_unique_elements(e))}
    

    【讨论】:

    • 编写第一个代码的更有效方法是使用|=,而不是在每次迭代时创建一个新集合。您也可以调用update 方法,这可能比使用运算符更清晰。
    • 这对数字很有效,但唯一的问题是它不能处理字母。
    • @ThatGuy 你能举个例子吗
    • @ThatGuy 你的意思是extract_unique_elements(['a',['a','b',['c','b',['e']]]])
    • @ThatGuy 返回结果符合预期,对吧?还是我错过了什么?
    【解决方案3】:

    或者

    def myflatten(l):
        if type(l) != list:
            return([l])
        elif type(l) == list:
            if len(l) == 1:
                return(myflatten(l[0]))
            else:
                res = myflatten(l[0]) + myflatten(l[1:])
                return(res)
    
    print(set(myflatten([1,[2,1,[5,5,[2]]]])))
    #{1, 2, 5}
    
    # OR (rectified):
    
    def myflatten(l):
        if not isinstance(l, list):
            return [l]
        else:
            if len(l) == 1:
                return myflatten(l[0])
            else:
                res = myflatten(l[0]) + myflatten(l[1:])
                return res
    

    【讨论】:

    • 这段代码中有许多非pythonic的东西:isinstance(SomeType, some_object)type(some_object) == SomeType 更受欢迎,因为前者尊重子类。 return 不是一个函数,你不需要在你返回的值周围加上括号。您无需在ifelif 中同时测试条件及其逆。如果if 被命中,您将永远不会测试elif 条件,如果它为假,elif 条件将始终为真。所以只需使用else。或者,由于您是从 if 返回的,您可以无条件地运行当前位于 else 块中的代码。
    猜你喜欢
    • 2022-12-12
    • 2015-04-26
    • 2021-11-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    相关资源
    最近更新 更多