2011-01-30 36 views
30

Mam listę z pustych list w nim:Python: Jak usunąć puste listy z listy?

list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 

Jak mogę usunąć pustych list, tak aby uzyskać:

list2 = ['text', 'text2', 'moreText'] 

Próbowałem list.remove („”), ale to nie robi nie działa.

+2

'''! = []', Dlatego '.remove' nie działa. Ale nadal jest to złe rozwiązanie (albo sprawdzisz, czy przed słowem znajduje się '[] in list1' -" O (n ** 2) "- lub złap błąd, który poda inaczej - brzydko). – delnan

+1

tak niesamowite, gdy uświadomiłeś sobie, że chociaż twoje pytanie nie jest powszechne, ale ktoś dawno temu opublikował to i zostało pięknie odebrane! Uwielbiam SO –

Odpowiedz

47

Spróbuj

list2 = [x for x in list1 if x != []] 

Jeśli chcesz pozbyć się wszystkiego, co jest "falsy", na przykład pustych strun, puste krotki, Zera, można również użyć

list2 = [x for x in list1 if x] 
+0

+1 za wzmiankę o innym sposobie myślenia i różnicach. – delnan

+0

Wiem, że to jest stare, ale wciąż widzę tę metodę nawiasów klamrowych i nie mogę znaleźć niczego za pośrednictwem Google (prawdopodobnie dlatego, że Google nie robi interpunkcji). Jak to się nazywa, żebym mógł dowiedzieć się więcej o tym, co się tam naprawdę dzieje? – David

+1

@David: [Lista ze zrozumieniem] (https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) i [Wyrażenia generatora] (https://docs.python.org/3/tutorial /classes.html#generator-expressions). Istnieją również słownictwo ze zrozumieniem słownika i zestawienie ze zrozumieniem. –

0

kilka możliwości:

filter(lambda x: len(x) > 0, list1) # Doesn't work with number types 
filter(None, list1) # Filters out int(0) 
filter(lambda x: x==0 or x, list1) # Retains int(0) 

przykładową sesję:

Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on 
win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
>>> filter(lambda x: len(x) > 0, list1) 
['text', 'text2', 'moreText'] 
>>> list2 = [[], [], [], [], [], 'text', 'text2', [], 'moreText', 0.5, 1, -1, 0] 
>>> filter(lambda x: x==0 or x, list2) 
['text', 'text2', 'moreText', 0.5, 1, -1, 0] 
>>> filter(None, list2) 
['text', 'text2', 'moreText', 0.5, 1, -1] 
>>> 
+0

-1: 'len (x)> 0' jest zasadniczo takie samo jak' bool (x) 'lub po prostu' x'. – lunaryorn

+1

lub Brak dla 'filter()' –

+0

+1: @RC. Jeśli masz typy liczb na liście, nie możesz na nie dzwonić. Jeśli masz '0', zostanie odfiltrowane przez' Brak'. W przeciwnym razie podoba mi się ta odpowiedź. –

3
>>> list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
>>> list2 = [e for e in list1 if e] 
>>> list2 
['text', 'text2', 'moreText'] 
+1

Czy ktoś może to edytować! Nie mogę uzyskać opcji formatowania. – user225312

+0

zrobione (musisz użyć '{}') –

+0

@RC: Dzięki! Wiem o tym, ale z jakiegoś dziwnego powodu nie jest to widoczne (nie ma opcji). – user225312

36

Można użyć filter() zamiast zrozumienie listy:

list2 = filter(None, list1) 

Jeśli None zostanie użyty jako pierwszy argument dla filter(), odfiltrowuje każdą wartość z podanej listy, która jest False w kontekście boolowskim. Obejmuje to puste listy.

To może być nieznacznie szybciej niż listowego, ponieważ wykonuje tylko jedną funkcję w Pythonie, reszta jest wykonywana w C.

+0

dlaczego ta odpowiedź nie zawiera większej liczby upvotes i/lub może być zaakceptowaną odpowiedzią? –

+0

@ MattO'Brien b/c wielu programistów Pythona unika 'filter()', jak również 'lambda',' map() 'i' reduce() '; dotyczy to [samego Guido] (http://www.artima.com/weblogs/viewpost.jsp?thread=98196), chociaż ten post jest nieco stary. Zwykle wolę rozumienie list b/c klarowność jest często ważniejsza niż niewielkie przyspieszenie za pomocą tych metod i operatora 'lambda'. Biorąc to pod uwagę, ten przypadek jest trywialny b/c, jest bardzo jasne, co to jest intencja programisty. – BoltzmannBrain

5

Wywołanie filter z None będzie odfiltrować wszystkie wartości falsey z listy (która pusta lista to)

list2 = filter(None, list1) 
1

Znalazłem to pytanie, ponieważ chciałem zrobić to samo co OP. Chciałabym dodać następującą obserwację:

iteracyjny sposób (user225312 Sven Marnach):

list2 = [x for x in list1 if x] 

zwróci list obiekt w python3 i python2. Zamiast sposób filtr (lunaryorn, Imran) będą różnie zachowywać nad wersjach:

list2 = filter(None, list1) 

To zwróci filter obiekt w python3 i list w python2 (patrz this question znaleziony w tym samym czasie). Jest to niewielka różnica, ale należy wziąć to pod uwagę przy tworzeniu kompatybilnych skryptów.

Nie ma to żadnego wpływu na wydajność tych rozwiązań. W każdym razie przedmiotem filtr można przywrócić do listy za pomocą:

list3 = list(list2) 
0

Musiałem odfiltrować puste elementy z bardziej skomplikowanych obiektów zagnieżdżonych. Zrobiłem funkcję rekursywną, aby to zrobić. Zobacz my SO answer here.

0
a = [[1,'aa',3,12,'a','b','c','s'],[],[],[1,'aa',7,80,'d','g','f',''],[9,None,11,12,13,14,15,'k']] 

b=[] 
for lng in range(len(a)): 
     if(len(a[lng])>=1):b.append(a[lng]) 
a=b 
print(a) 

[[1 'aa' 3,12 'a', 'b', 'c', 'S'] [1, 'aa', 7 80, 'd', 'g', 'f', ''], [9 Brak, 11,12,13,14,15, 'k']]

-1
list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
list2 = [] 
for item in list1: 
    if item!=[]: 
     list2.append(item) 
print(list2) 

moc wyjściowa:

['text', 'text2', 'moreText'] 
+0

Tylko odpowiedzi kodowe nie są bardzo przydatne same. Pomogłoby to w dodaniu szczegółów wyjaśniających, jak/dlaczego odpowiada na pytanie. To powiedziawszy, nie jestem pewien, czy ta odpowiedź dodaje żadnej wartości w stosunku do wszystkich pozostałych do tego pięcioletniego pytania. – SiHa