将多级列表列表展平为单个级别

时间:2017-12-26 19:51:19

标签: python python-3.x list concatenation flatten

我需要展平多级列表的所有级别:

import itertools

pool = [[[[[0,2],[1,3]],[[3,2],[1,0]]],"PdPd","PrisonerDilemma"], 
[[[[0,3],[1,2]],[[2,3],[1,0]]],"ShSh","StagHunt"],
[[[[1,2],[3,0]],[[3,2],[1,0]]],"ChCh","Chicken"],
[[[[2,1],[0,3]],[[3,1],[0,2]]],"BaBa","Battle"]]

def flat3 (pool):
    for game in pool:
        l = list(itertools.chain.from_iterable(game[0]))
        print(l)

结果:

flat3 (pool)
[[0, 2], [1, 3], [3, 2], [1, 0]]
[[0, 3], [1, 2], [2, 3], [1, 0]]
[[1, 2], [3, 0], [3, 2], [1, 0]]
[[2, 1], [0, 3], [3, 1], [0, 2]]

因此,目标是隔离并返回每个项目中的第一个级别,仅包含数字,例如:

[[[[[0,2],[1,3]],[[3,2],[1,0]]],"PdPd","PrisonerDilemma"]

然后我需要将所有内容夷为平地,例如:

[0,2,1,3,3,2,1,0]

我知道这个主题有很多材料,我已经找到并尝试了很多方法来做到这一点,但似乎没有一个方法可以使用多个级别,我想知道是否有一种有效的方法来做到这一点,多次不重复相同的命令。有谁可以帮助我?

谢谢

4 个答案:

答案 0 :(得分:2)

与往常一样,第一步是查看您的数据结构。

el = [
         [
             [[0,2],[1,3]],
             [[3,2],[1,0]]
         ],
         "PdPd",
         "PrisonerDilemma"
     ]

这是您结构中的每个元素。我们暂时忽略这个最外层的结构几乎肯定不应该是一个列表(它看起来更像是一个元组),只关注我们所拥有的东西。

el[0] = [ [[0, 2], [1, 3]],
          [[3, 2], [1, 0]] ]
el[1] = # a string
el[2] = # another string, we don't care about these

现在我们将其缩减为LISTS数字列表。这个我们可以操作。

def flatten(lst):
    for el in lst:
        if isinstance(el, list):  # N.B. this only works for lists, not general
                                  # collections e.g. sets, tuples, dicts, etc...
            # recurse
            yield from flatten(el)
        else:
            # generate
            yield el

您的结果是将此函数应用于最外面列表中每个项目的第一个元素。

result = [flatten(sublst[0]) for sublst in big_list]

请注意,这会创建一个生成器对象列表,需要使用它们来实际生成值。如果您出于某种原因确实需要列表,请明确地转换为列表:

result = [list(flatten(sublst[0])) for sublst in big_list]

答案 1 :(得分:2)

def flat(pool):
    res = []
    for v in pool:
        if isinstance(v, list):
          res += flat(v)
        else:
          if isinstance(v, int):
            res.append(v)
    return res  

demo

答案 2 :(得分:1)

创建一个函数,返回一个展平的数字列表。

此功能采用列表并查看每个项目。如果item是数字,请将其添加到返回列表中。如果是列表,则在此列表上递归调用该函数,并将返回的列表添加到调用函数的返回列表中。如果是str或其他内容,请忽略该项目。

答案 3 :(得分:1)

如果你的最后一个输出是每个嵌套列表的所有数字,那么你可以使用正则表达式获取它们:

  

一线解决方案:

import re

pool = [[[[[0,2],[1,3]],[[3,2],[1,0]]],"PdPd","PrisonerDilemma"],
[[[[0,3],[1,2]],[[2,3],[1,0]]],"ShSh","StagHunt"],
[[[[1,2],[3,0]],[[3,2],[1,0]]],"ChCh","Chicken"],
[[[[2,1],[0,3]],[[3,1],[0,2]]],"BaBa","Battle"]]

pattern=r'\d+'

print([[int(i) for i in re.findall(pattern,str(i))] for i in pool ])

输出:

[[0, 2, 1, 3, 3, 2, 1, 0], [0, 3, 1, 2, 2, 3, 1, 0], [1, 2, 3, 0, 3, 2, 1, 0], [2, 1, 0, 3, 3, 1, 0, 2]]
  

详细解决方案:

以上列表理解与:

相同
for i in pool:
    nested_list=[]
    for i in re.findall(pattern, str(i)):
        nested_list.append(int(i))
    print(nested_list)