2013-06-27 29 views
9

Python'da liste anlama özelliğini kullanarak bir listeyi düzleştirmeye çalışıyorum. Benim listem biraz ben alıyorum liste anlama yoluyla listemi düzleştirmek için aynı mantığı kullanılan Sonraliste anlaşması listeden listenin listesini göster

def flat(listoflist): 
    for item in listoflist: 
      if type(item) != list: 
        print item 
      else: 
        for num in item: 
          print num 
>>> flat(list1) 
1 
2 
3 
4 
5 
6 
7 
8 

bu kodu yazdım sadece listenin bu listede baskı daha sonra tek tek öğe için

[[1, 2, 3], [4, 5, 6], 7, 8] 

gibidir aşağıdaki hata

list2 = [item if type(item) != list else num for num in item for item in list1] 
    Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    TypeError: 'int' object is not iterable 

Liste türünü kullanarak bu liste liste türünü nasıl düzleştirebilirim?

cevap

6
>>> from collections import Iterable 
>>> from itertools import chain 

Tek astar Python 3 var olduğuna dikkat yapın:

>>> list(chain.from_iterable(item if isinstance(item,Iterable) and 
        not isinstance(item, basestring) else [item] for item in lis)) 
[1, 2, 3, 4, 5, 6, 7, 8] 

Okunabilir bir sürüm:

>>> def func(x):           #use `str` in py3.x 
...  if isinstance(x, Iterable) and not isinstance(x, basestring): 
...   return x 
...  return [x] 
... 
>>> list(chain.from_iterable(func(x) for x in lis)) 
[1, 2, 3, 4, 5, 6, 7, 8] 
#works for strings as well 
>>> lis = [[1, 2, 3], [4, 5, 6], 7, 8, "foobar"] 
>>> list(chain.from_iterable(func(x) for x in lis))                 
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar'] 

iç içe liste anlama kullanarak: (itertools.chain kıyasla yavaş gitmek):

>>> [ele for item in (func(x) for x in lis) for ele in item] 
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar'] 
+1

Bu, 2.x kullanan asker için harikadır, ancak 3.x kullanıcılarının yerine str'yi kullanması gereken bir nottur. 'basestring'. –

+0

@Ashwini Öğelerim tamsayı yerine tipte ise, ne yapılmalı? –

+0

@AnuragSharma küçük örnek? –

3

Yapamayacağınız bir sayıdan (yani hatadan) yineleme yapmaya çalışıyorsunuz.

Eğer piton 2.7 kullanıyorsanız:

>>> from compiler.ast import flatten 
>>> flatten(l) 
[1, 2, 3, 4, 5, 6, 7, 8] 

Ama modül karakteri artık ve artık

+1

Yazım denetimi listeleri kötü bir fikirdir. Bu daha az esnek hale getirir. –

+1

'' [[1, 2, 3], [4, 5, 6], 7, 888] 'ise, ilk çözüm' [1, 2, 3, 4, 5, 6, 7, 8, 8, 8]. – falsetru

+0

İlk biti kaldırdım, ama diğer çözümümün python 3'te çalışmayacağı bir utanç vericidir. – TerryA

3

alternatif bir çözüm bir jeneratör kullanarak:

import collections 

def flatten(iterable): 
    for item in iterable: 
     if isinstance(item, collections.Iterable) and not isinstance(item, str): # `basestring` < 3.x 
      yield from item # `for subitem in item: yield item` < 3.3 
     else: 
      yield item 

>>> list(flatten([[1, 2, 3], [4, 5, 6], 7, 8])) 
[1, 2, 3, 4, 5, 6, 7, 8] 
+2

+1 Hiçbir zaman 'from from statement ifadesini bilmiyordum. –

3

kimse zamanki cevabı verdi:

def flat(l): 
    return [y for x in l for y in x] 

StackOverflo'da bu sorgunun yüzlerce kopyası var. w.

+1

Kodunuz, listesinin yinelenemez nesneler, yani tamsayılar içerdiğinden, sağlanan OP listesi için çalışmaz. Ancak kodunuz, listedeki her öğe yinelenen bir nesne ise işe yarar. Aşağıdaki yorumuma bakın. – JDG

+1

Bunu işaretlediğiniz için teşekkür ederim - bununla uğraşmak için bir an bulmalıyım ve kavramaya geleceğim ... – GreenAsJade

İlgili konular