如何解压深嵌套的可迭代结构

时间:2016-08-02 12:50:13

标签: python python-3.x iterable iterable-unpacking

比如说我有一个包含许多子元素的结构,其中一些子结构是结构:

v = [1, 2, 3, [4, (5, 6)]]

如何将这些解包为一系列只包含结构内容但不包含结构的名称?

在使用已加星标的表达式时尝试a, b, c, d, e, f = v引发ValueError会为名称指定结构。我怎样才能解压缩它们以获得:

print(a, b, c, d, e, f)

打印:

1 2 3 4 5 6

2 个答案:

答案 0 :(得分:11)

分配是递归定义的,您需要 use parentheses () and/or square brackets [] to enclose target names 并匹配迭代的嵌套结构。在你的情况下:

a, b, c, (d, (e, f)) = v
print(a, b, c, d, e, f) 
1 2 3 4 5 6

同样,如果语义没有变化,您可以使用[]来表示结构:

a, b, c, [d, [e, f]] = v
print(a, b, c, d, e, f) 
1 2 3 4 5 6

或当然,将它们混合起来。

然后,Python将解包v并正常分配前3个值,然后解压缩(d, (e, f))的内容并分配d,然后再解包(e, f)并执行相同的操作

如果您导入dis模块并使用dis.dis反汇编语句,则可以看到这种情况:

dis.dis('a, b, c, (d, (e, f)) = v')
  1           0 LOAD_NAME                0 (v)
              3 UNPACK_SEQUENCE          4      # <- first unpack
              6 STORE_NAME               1 (a)
              9 STORE_NAME               2 (b)
             12 STORE_NAME               3 (c)
             15 UNPACK_SEQUENCE          2      # <- second unpack
             18 STORE_NAME               4 (d)
             21 UNPACK_SEQUENCE          2      # <- third unpack
             24 STORE_NAME               5 (e)
             27 STORE_NAME               6 (f)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE

通常,要解压缩任意嵌套结构,请匹配赋值左侧的结构(target-list):

v = [1, [2, [3, [4, 5]]]]    
[a, [b, [c, [d, e]]]] = v    
print(a, b, c, d, e)
1 2 3 4 5

外部[]当然是不必要的,只需添加它们即可显示简单匹配结构就足够了。

答案 1 :(得分:4)

您可能考虑的另一个选择是展平结构然后分配它。

def flatten(container):
    for i in container:
        if isinstance(i, (list,tuple)):
            for j in flatten(i):
                yield j
        else:
            yield i

然后

a, b, c, d, e, f = flatten(v)