Unwrap/Flatten 不平衡的字符串列表列表

Unwrap/Flatten unbalanced List of Lists with Strings

考虑到我有以下列表:

['graph_edges', ['graph_nodes'], ['graph_nodes'], ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']]]

我希望将它转换成类似的东西:

['graph_edges', 'graph_nodes', 'graph_nodes', 'graph_edges2', 'graph_nodes2', 'graph_nodes2'] 
# I would list(set(thislist)) afterwards

There is a ton of solutions out there already 但对我来说很奇怪,我无法完成任何有意义的事情:

from functools import reduce
import operator
reduce(operator.concat,['graph_edges', ['graph_nodes'], ['graph_nodes'], ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']]])
*** TypeError: can only concatenate str (not "list") to str

sum:

sum(['graph_edges', ['graph_nodes'], ['graph_nodes'], ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']]], [])

这条单线展开太多:

> [item for sublist in ['graph_edges', ['graph_nodes'], ['graph_nodes'], ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']]] for item in sublist]
['g', 'r', 'a', 'p', 'h', '_', 'e', 'd', 'g', 'e', 's', 'graph_nodes', 'graph_nodes', 'graph_edges2', ['graph_nodes2'], ['graph_nodes2']]

或使用 itertools:

>!list(itertools.chain(*lol))
['g', 'r', 'a', 'p', 'h', '_', 'e', 'd', 'g', 'e', 's', 'graph_nodes', 'graph_nodes', 'graph_edges2', ['graph_nodes2'], ['graph_nodes2']]

免责声明:我在 ipdb 中尝试过这些,所以总是有可能出现错误

我目前(不工作)且非常不满意的解决方案是:

retlist= []
dedefined=['graph_edges', ['graph_nodes'], ['graph_nodes'], ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']]]

for element in dedefined:
    if isinstance(element,list):
            retlist+=self.getSingleElement(element)
        else:
            retlist.append(element)
    return list(set(retlist))

@classmethod
def getSingleElement(cls,element):
    if isinstance(element,list):            
            return cls.getSingleElement(*element)
    else: return element

element 达到 ['graph_edges2', ['graph_nodes2'], ['graph_nodes2']] 时它失败了,但我将无法想到有意义的事情。我可以制作一个生成新值而不是 returns 的生成器,或者遍历每个元素并使其成为一个可以解散的列表。但是 none 这些想法对我来说很有说服力

您需要使用递归来解释列表可以任意深度嵌套的事实:

def flatten(lst):
    result = []
    for item in lst:
        # You can use:
        # if not isinstance(item, list):
        # if you have other items besides integers in your nested list.
        if isinstance(item, str):
            result.append(item)
        else:
            result.extend(flatten(item))
    return result

这输出:

['graph_edges', 'graph_nodes', 'graph_nodes',
 'graph_edges2', 'graph_nodes2', 'graph_nodes2']
def flatten(array):
    flat = []
    for member in array:
        if isinstance(member, (tuple, list)):
            flat.extend(flatten(member))
        else:
            flat.append(member)
    return flat