Usuń puste ciągi z listy ciągów

Chcę usunąć wszystkie puste ciągi z listy ciągów w Pythonie.

Mój pomysł wygląda tak:

while '' in str_list:
    str_list.remove('')
Czy jest jeszcze jakiś pythoniczny sposób na to?
Author: zerodx, 2010-10-02

14 answers

Użyłbym filter:

str_list = filter(None, str_list) # fastest
str_list = filter(bool, str_list) # fastest
str_list = filter(len, str_list)  # a bit slower
str_list = filter(lambda item: item, str_list) # slower than list comprehension

Python 3 zwraca iterator z filter, więc powinien być zawinięty w wywołanie do list()

str_list = list(filter(None, str_list)) # fastest

(itd.)

Testy:

>>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.4797441959381104
>>> timeit('filter(bool, str_list)', 'str_list=["a"]*1000', number=100000)
2.4788150787353516
>>> timeit('filter(len, str_list)', 'str_list=["a"]*1000', number=100000)
5.2126238346099854
>>> timeit('[x for x in str_list if x]', 'str_list=["a"]*1000', number=100000)
13.354584932327271
>>> timeit('filter(lambda item: item, str_list)', 'str_list=["a"]*1000', number=100000)
17.427681922912598
 842
Author: livibetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-17 19:16:25

Składanie Listy

strings = ["first", "", "second"]
[x for x in strings if x]

Wyjście: ['first', 'second']

Edit: skrócony zgodnie z sugestią

 163
Author: Ib33X,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 04:38:24

Filtr faktycznie ma do tego specjalną opcję:

filter(None, sequence)

Odfiltruje wszystkie elementy, które oceniają Na False. Nie trzeba używać rzeczywistego wywołania tutaj, takiego jak bool, len i tak dalej.

Jest równie szybki jak mapa (bool, ...)

 57
Author: Ivo van der Wijk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-02 12:04:30
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']

>>> ' '.join(lstr).split()
['hello', 'world']

>>> filter(None, lstr)
['hello', ' ', 'world', ' ']

Porównaj czas

>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
4.226747989654541
>>> timeit('filter(None, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.0278358459472656

Zauważ, że filter(None, lstr) nie usuwa pustych łańcuchów ze spacją ' ', tylko usuwa '' podczas gdy ' '.join(lstr).split() usuwa oba.

Użycie filter() z usuniętymi znakami spacji zajmuje dużo więcej czasu:

>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
 16
Author: Aziz Alto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-26 10:25:40

Zamiast if x, użyłbym if X != " w celu wyeliminowania pustych ciągów. TAK:

str_list = [x for x in str_list if x != '']

Spowoduje to zachowanie żadnego typu danych na liście. Ponadto, jeśli Twoja lista ma liczby całkowite i 0 jest jedną z nich, również zostanie zachowana.

Na przykład,

str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
 9
Author: thiruvenkadam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-08 14:49:28

Odpowiedź od @ Ib33X jest super. Jeśli chcesz usunąć każdy pusty ciąg, po rozebraniu. musisz też użyć metody paska. W przeciwnym razie zwróci również pusty łańcuch, jeśli ma białe spacje. Jak, "" będzie również ważne dla tej odpowiedzi. Tak, można osiągnąć przez.

strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]

Odpowiedź na to pytanie będzie ["first", "second"].
Jeśli chcesz zamiast tego użyć metody filter, możesz zrobić jak
list(filter(lambda item: item.strip(), strings)). To daje ten sam wynik.

 9
Author: ssi-anik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-14 16:29:13

W zależności od wielkości listy, może być najbardziej wydajny, jeśli używasz listy.Usuń () zamiast tworzyć nową listę:

l = ["1", "", "3", ""]

while True:
  try:
    l.remove("")
  except ValueError:
    break

Ma tę zaletę, że nie tworzy się nowej listy, ale wadą jest konieczność przeszukiwania od początku za każdym razem, chociaż w przeciwieństwie do używania {[1] } jak zaproponowano powyżej, wymaga przeszukiwania tylko raz na każde wystąpienie '' (z pewnością istnieje sposób, aby zachować najlepszą z obu metod, ale jest to bardziej skomplikowane).

 5
Author: Andrew Jaffe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-02 13:22:10

Użycie filter:

newlist=filter(lambda x: len(x)>0, oldlist) 

Wadą używania filtra, jak wskazano, jest to, że jest wolniejszy niż alternatywy; ponadto, {[3] } jest zwykle kosztowne.

Albo możesz wybrać najprostszy i najbardziej iteracyjny ze wszystkich:

# I am assuming listtext is the original list containing (possibly) empty items
for item in listtext:
    if item:
        newlist.append(str(item))
# You can remove str() based on the content of your original list
Jest to najbardziej intuicyjna metoda i robi to w przyzwoitym czasie.
 5
Author: Aamir Mushtaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-03 17:12:54

Jak donosi Aziz Alto filter(None, lstr) nie usuwa pustych łańcuchów ze spacją ' ', ale jeśli masz pewność, że lstr zawiera tylko łańcuch, możesz użyć filter(str.strip, lstr)

>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(str.strip, lstr)
['hello', 'world']

Porównaj czas na moim komputerze

>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.356455087661743
>>> timeit('filter(str.strip, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
5.276503801345825

Najszybszym rozwiązaniem do usunięcia '' i pustych łańcuchów ze spacją ' ' pozostaje ' '.join(lstr).split().

Jak podano w komentarzu, sytuacja jest inna, jeśli Twoje ciągi znaków zawierają spacje.

>>> lstr = ['hello', '', ' ', 'world', '    ', 'see you']
>>> lstr
['hello', '', ' ', 'world', '    ', 'see you']
>>> ' '.join(lstr).split()
['hello', 'world', 'see', 'you']
>>> filter(str.strip, lstr)
['hello', 'world', 'see you']

Widać, że filter(str.strip, lstr) zachowuje ciągi ze spacjami, ale ' '.join(lstr).split() podzieli te struny.

 4
Author: Paolo Melchiorre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 08:06:11

Należy pamiętać, że jeśli chcesz zachować białe spacje w łańcuchu , możesz usunąć je nieumyślnie za pomocą niektórych metod. Jeśli masz tę listę

['hello world','',', 'hello'] what you may want ['hello world','hello']

Najpierw Przytnij listę, aby przekonwertować dowolny typ białej spacji na pusty łańcuch:

space_to_empty = [x.strip() for x in _text_list]

Następnie usuń pusty łańcuch z listy

space_clean_list = [x for x in space_to_empty if x]
 2
Author: Reihan_amn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-27 09:09:06

W celu wyeliminowania pustek po rozebraniu:

slist = map(lambda s: s and s.strip(), slist)
slist = filter(None, slist)

Niektóre Plusy:

  • leniwy, oparty na generatorach, do zapisywania pamięci;
  • przyzwoita zrozumiałość kodu;
  • Szybko, selektywnie używając wbudowanych i złożonych.

    def f1(slist):
        slist = [s and s.strip() for s in slist]
        return list(filter(None, slist))
    
    def f2(slist):
        slist = [s and s.strip() for s in slist]
        return [s for s in slist if s]
    
    
    def f3(slist):
        slist = map(lambda s: s and s.strip(), slist)
        return list(filter(None, slist))
    
    def f4(slist):
        slist = map(lambda s: s and s.strip(), slist)
        return [s for s in slist if s]
    
    %timeit f1(words)
    10000 loops, best of 3: 106 µs per loop
    
    %timeit f2(words)
    10000 loops, best of 3: 126 µs per loop
    
    %timeit f3(words)
    10000 loops, best of 3: 165 µs per loop
    
    %timeit f4(words)
    10000 loops, best of 3: 169 µs per loop
    
 0
Author: ankostis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-15 10:40:07
str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']

for item in str_list:
    if len(item) < 1:  
        str_list.remove(item)
Krótko i słodko.
 -2
Author: coreyevanf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 03:13:58

Przeprowadź pętlę przez istniejącą listę łańcuchów, a następnie sprawdź pusty łańcuch, jeśli nie jest pusty, wypełnij nową listę łańcuchów niepustymi wartościami, a następnie zastąp starą listę łańcuchów nową listą łańcuchów

 -3
Author: Roland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-02 11:27:33

filter(None, str) nie usuwa pustych ciągów ze spacją ' ', tylko usuwa "'i''.

join(str).split() usuwa oba. ale jeśli twój element listy ma spację, to zmieni twoje elementy listy również dlatego, że najpierw łączy wszystkie elementy listy, a następnie spacja, więc powinieneś użyć : -

str = ['hello', '', ' ', 'world', ' ']
print filter(lambda x:x != '', filter(lambda x:x != ' ', str))

Usunie oba i nie wpłynie również na twoje elementy Like: -

str = ['hello', '', ' ', 'world ram', ' ']
print  ' '.join(lstr).split()
print filter(lambda x:x != '', filter(lambda x:x != ' ', lstr))

Wyjście: -

['hello', 'world', 'ram'] ' '.join(lstr).split()
['hello', 'world ram']

 -3
Author: Radhamohan Parashar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 12:55:24