2013-01-09 7 views
15

Używam Beautiful Soup w Pythonie do zeskanowania niektórych danych z plików HTML. W niektórych przypadkach, Beautiful Soup zwraca listy, które zawierają zarówno obiekty string, jak i . Chciałbym odfiltrować wszystkie obiekty NoneType.Natywna funkcja Pythona do usuwania elementów NoneType z listy?

W języku Python, listy zawierające obiekty NoneType nie są możliwe do sprawdzenia, więc zrozumienie listy nie jest możliwe. W szczególności, jeśli mam listę lis zawierającą NoneTypes i próbuję zrobić coś takiego jak [x for x in lis (some condition/function)], Python zgłasza błąd TypeError: argument of type 'NoneType' is not iterable.

Jak widzieliśmy w artykule other posts, można łatwo zaimplementować tę funkcję w funkcji zdefiniowanej przez użytkownika. Oto mój smak tego:

def filterNoneType(lis): 
    lis2 = [] 
    for l in links: #filter out NoneType 
     if type(l) == str: 
      lis2.append(l) 
    return lis2 

Jednak chciałbym użyć wbudowanej funkcji Pythona, jeśli istnieje. Zawsze lubię upraszczać mój kod, jeśli to możliwe. Czy Python ma wbudowaną funkcję, która może usuwać obiekty z listy z obiektów NoneType?

+0

Mylisz się, że listy zawierające "Brak" nie są możliwe do sprawdzenia. Prawdopodobnie (przypadkowo) próbujesz powtórzyć sam "Brak": '[x dla x w Brak]'. –

Odpowiedz

39

Myślę, że najczystszym sposobem na to byłoby:

#lis = some list with NoneType's 
filter(None, lis) 
+21

To jest złe, ponieważ będzie również usuń elementy '0',' False' i ''''. – thomaspaulb

+12

Wystarczająco fair. Możesz użyć 'filter (lambda x: x! = None, lis)' then. – Abs

18

Można to zrobić przy użyciu listowych:

clean = [x for x in lis if x != None] 

Jak zauważył w komentarzach można też użyć is not, nawet jeśli zasadniczo kompiluje do tego samego kodu bajtowego:

clean = [x for x in lis if x is not None] 

Mogłabyś również użyty filter (uwaga: to również będzie filtrować puste ciągi, jeśli chcesz mieć większą kontrolę nad tym, co filtrujesz, możesz przekazać funkcję zamiast None):

clean = filter(None, lis) 

Zawsze istnieje podejście itertools, jeśli chcesz bardziej wydajne zapętlenie, ale te podstawowe podejścia powinny działać w większości przypadków.

+1

Zgodnie z PEP 8 powinieneś używać 'is not' zamiast'! = 'W porównaniu do singletonów. – Tim

+0

filter() przyjmuje funkcję jako pierwszy argument –

+1

@ThorstenKranz, jeśli pierwszym parametrem jest "None", to odfiltrowuje wszystkie wpisy "fałszywe" ('None', puste ciągi, zera itd.). – bereal

1

Można łatwo usunąć wszystkie NoneType przedmiotów z listy na podstawie listy ze zrozumieniem:

lis = [i for i in lis if i is not None] 
4

listy ze zrozumieniem, jak inne odpowiedzi zaproponował lub dla kompletności wywodu:

clean = filter(lambda x: x is not None, lis) 

Jeśli lista jest ogromna, podejście iteracyjne jest lepsze:

from itertools import ifilter 
clean = ifilter(lambda x: x is not None, lis) 
Powiązane problemy