2013-10-27 55 views
1

我列出的清單列表...Python的扁平列表(但不是所有的方式)

A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ] 

以下功能輸出[1, 3, 3, 5, 4, 4, 5, 3]

def flatten(a): 
    b = [] 
    for c in a: 
     if isinstance(c, list): 
      b.extend(flatten(c)) 
     else: 
      b.append(c) 
    return b 

不過,我想停下來壓扁在最後一級,所以我得到[ [1,3], [3,5], [4,4], [5,3] ]

+0

這就要求列表的掃描,看看是否有任何列表包含。 –

+0

@MartijnPieters是的,我明白了,但問題是最後一個元素是列表中的一個列表。 –

+0

@GamesBrainiac:看到我的答案;只是在扁平化之前測試列表。 –

回答

4

你可以在扁平化之前測試包含列表:

def flatten(a): 
    b = [] 
    for c in a: 
     if isinstance(c, list) and any(isinstance(i, list) for i in c): 
      b.extend(flatten(c)) 
     else: 
      b.append(c) 
    return b 

演示:

>>> def flatten(a): 
...  b = [] 
...  for c in a: 
...   if isinstance(c, list) and any(isinstance(i, list) for i in c): 
...    b.extend(flatten(c)) 
...   else: 
...    b.append(c) 
...  return b 
... 
>>> A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ] 
>>> flatten(A) 
[[1, 3], [3, 5], [4, 4], [5, 3]] 

此嘗試是儘可能高效能的情況下; any()只需要測試,直到找到列表,而不是所有元素。

+0

做得很好,最後我做了同樣的事情,但我用'chain.from_iterable'。 –

2
A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ] 

print [child[0] if isinstance(child[0], list) else child for item in A for child in item] 

輸出

[[1, 3], [3, 5], [4, 4], [5, 3]] 

注:該解決方案是隻用於這個問題。這不是一個通用列表扁平解決方案。

同樣的想法,與itertools.chain

from itertools import chain 
print [item[0] if isinstance(child[0], list) else item for item in chain(*A)] 

輸出

[[1, 3], [3, 5], [4, 4], [5, 3]] 
+0

使用'isinstance()'來測試類型; 'type(...)== typeobj'是非常嚴格的。即使'isinstance()'不可用,無論如何你應該使用'is typeobj'。 –

+0

@MartijnPieters爲什麼它是限制性的?你能請求xplain嗎? – thefourtheye

+0

'isinstance(ob,list)'對於子類也是'True','type(ob)is list'只允許列表對象,而不允許子類。 –