2016-08-02 85 views
4

例如說我有一個包含很多子要素其中一些結構的結構:如何解開深層嵌套迭代結構

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 

回答

10

分配是遞歸定義,你需要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 

一般來說,解壓任意嵌套的結構,在分配的左側匹配結構(目標-list):

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

[]是,當然,沒有必要,只是增加他們以顯示簡單地相匹配的結構就足夠了。

3

您可能考慮的另一個選擇是平坦化結構,然後分配它。

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) 
+0

你可以使用'isinstance(I,集裝箱)'和'Container'從'collections.abc'爲了趕所有容器,而不僅僅是'list'和'元組'類型。 –

+0

@JimFasarakisHilliard:雖然你可能想要明確排除或特殊情況下的'str'(可能還有'bytes'和相關類型),因爲它們被視爲Container,但通常被用作標量。 – ShadowRanger