Я хочу удалить все пустые строки из списка строк в python.Удалить пустые строки из списка строк
Моя идея выглядит следующим образом:
while '' in str_list:
str_list.remove('')
Есть ли еще вещий способ сделать это?
Я хочу удалить все пустые строки из списка строк в python.Удалить пустые строки из списка строк
Моя идея выглядит следующим образом:
while '' in str_list:
str_list.remove('')
Есть ли еще вещий способ сделать это?
I будет использовать 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 возвращает итератор из filter
, поэтому должны быть обернуты в вызове list()
str_list = list(filter(None, str_list)) # fastest
(и т.д.)
Тесты:
>>> 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
или 'filter (len, str_list)' –
@ Ник, я слишком много думал. Как насчет использования 'bool'? Я сделал быстрый тест, это быстрее, чем 'len'. – livibetter
@livibetter, о да! Почему бы не изменить свой ответ, чтобы включить его? –
strings = ["first", "", "second"]
[x for x in strings if x]
Выход: ['first', 'second']
Edit: укороченный, как было предложено
Это решение в x9 раз медленнее, чем '' filter (None, my_list) ''. – Kee
@kee Не имеет значения, медленнее, чем filter(). список представляет собой питоновское решение. – Tritium21
@ Tritium21 Я думаю, что ** ** имеет значение, если вы хотите эффективный код, независимо от проблем с пифоном. –
Loop через существующий список строк, а затем проверить на пустую строку, если он не пустой заполнить новую строку список с непустыми значениями, а затем заменить старый список строк на новый список строк
В зависимости от размера вашего списка, это может быть наиболее эффективным, если вы используете list.remove(), а не создавать новый список:
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
Это имеет преимущество, не создавая новый список, но тот недостаток, из-за необходимости искать с начала каждый раз, хотя в отличие от использования while '' in l
, как было предложено выше, он требует только один раз на вхождение ''
(безусловно, есть способ сохранить лучшее из обоих методов, но это сложнее).
Вы можете редактировать список на месте, выполнив 'ary [:] = [e для e в ary if e]'. Гораздо чище и не использует исключения для потока управления. –
фильтр на самом деле имеет специальный вариант для этого:
filter(None, sequence)
Он будет отфильтровывать все элементы, которые оценивают в значение False. Не нужно использовать фактические вызываемые здесь такие как bool, len и т. Д.
Это столь же быстро, как карта (BOOL, ...)
Использование filter
:
newlist=filter(lambda x: len(x)>0, oldlist)
недостатков использования фильтра, как отметил, что это происходит медленнее, чем альтернативные варианты; тоже, lambda
обычно дорого.
Или вы можете пойти на самый простой и самый итерационный всего:
# 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
это наиболее интуитивный из методов, и делает это в приличное время.
Добро пожаловать в SO. Вы не были проигнорированы. На вас не напал какой-нибудь бесполезный спутник. Вам была предоставлена обратная связь. Усиление: ваш предложенный первый аргумент для фильтра хуже, чем 'lambda x: len (x)', который хуже, чем 'lambda x: x', который является наихудшим из 4-х решений в выбранном ответе. Правильное функционирование является предпочтительным, но недостаточно. Наведите курсор на кнопку downvote: он говорит: «Этот ответ не полезен». –
... и вы не должны использовать имя встроенного типа 'list' в качестве переменной. –
Вместо x, я бы использовал, если X! = '', Чтобы просто удалить пустые строки. Например:
str_list = [x for x in str_list if x != '']
Это сохранит тип данных None в вашем списке. Кроме того, если ваш список имеет целые числа, а 0 - один из них, он также будет сохранен.
Например,
str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
Если у ваших списков есть разрозненные типы (кроме None), у вас может возникнуть большая проблема. – Tritium21
Какие типы? Я пробовал с int и другими числовыми типами, строками, списками, tupes, sets и None и никаких проблем там. Я мог видеть, что если есть какие-то пользовательские типы, которые не поддерживают метод str, может возникнуть проблема. Должен ли я беспокоиться о других? – thiruvenkadam
Если у вас есть 'str_list = [None, '', 0," Hi ", ''," Hello "]', это признак плохо разработанного приложения. У вас не должно быть * более одного интерфейса (типа) и None в том же списке. – Tritium21
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(None, lstr)
['hello', ' ', 'world', ' ']
Сравнить время
>>> 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
Обратите внимание, что filter(None, lstr)
не удаляет пустые строки с пробелом ' '
, это только чернослив прочь ''
пока ' '.join(lstr).split()
удаляет обоих.
Чтобы использовать filter()
с пробельных строк удалены, это занимает гораздо больше времени:
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
не будет работать, если у вас есть пробел между строкой слова. например: ['hello world', '', 'hello', '']. >> ['helloworld', '', 'hello', ''] есть ли у вас какое-либо другое решение для хранения пробелов внутри элемента в списке, но удаление других? –
который не будет работать? –
'' .join (lstr) .split() Я пробовал! –
str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']
for item in str_list:
if len(item) < 1:
str_list.remove(item)
Короткий и сладкий.
filter(None, str)
не удаляет пустые строки с пробелом '', это только сокращает '' и ''.
join(str).split()
удаляет оба. но если ваш элемент списка, имеющего пространства, то это изменит список ваших элементов и потому, что это первое присоединение все ваши элементы списка затем spiting их пространство так, Вы должны использовать: -
str = ['hello', '', ' ', 'world', ' ']
print filter(lambda x:x != '', filter(lambda x:x != ' ', str))
Это удалит как и выиграл» т эффект ваши элементы также как: -
str = ['hello', '', ' ', 'world ram', ' ']
print ' '.join(lstr).split()
print filter(lambda x:x != '', filter(lambda x:x != ' ', lstr))
выход: -
[ 'привет', 'мир', 'баран'] < ------------- - выход ' '.join(lstr).split()
['hello', 'world ram']
Ответ от @ Ib33X замечательный. Если вы хотите удалить каждую пустую строку, после удаления. вам также нужно использовать метод полосы. В противном случае он также вернет пустую строку, если она имеет пробелы. Например, «» будет действительным и для этого ответа. Таким образом, может быть достигнуто.
strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
Ответ на этот вопрос будет ["first", "second"]
.
Если вы хотите использовать метод filter
, вы можете сделать это как
list(filter(lambda item: item.strip(), strings))
. Это дает тот же результат.
Лучший способ, на мой взгляд. Особенно, если в массиве есть целые строки вместо целых чисел. –
Как сообщает Aziz Altofilter(None, lstr)
не удаляет пустые строки с пробелом ' '
, но если вы уверены, что LSTR содержит только строку, которую вы можете использовать filter(str.strip, lstr)
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(str.strip, lstr)
['hello', 'world']
Сравнить время на моем компьютере
>>> 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
Самое быстрое решение для удаления ''
и пустые строки с пробелом ' '
остается ' '.join(lstr).split()
.
Как сообщается в комментарии, ситуация другая, если ваши строки содержат пробелы.
>>> 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']
Вы можете видеть, что filter(str.strip, lstr)
сохранить строки с пробелами на нем, но ' '.join(lstr).split()
разделит эти строки.
Это работает, только если ваши строки не содержат пробелов. В противном случае вы также разделите эти строки. – phillyslick
@BenPolinsky, так как вы сообщили, что решение 'join' будет разделять строки с пространством, но фильтр не будет. Спасибо за комментарий, я улучшил свой ответ. –
Для устранения пустышки после зачистки:
slist = map(lambda s: s and s.strip(), slist)
slist = filter(None, slist)
Некоторых PROs:
быстро, выборочно с использованием встроенных функций и понятий.
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
Имейте в виду, что если вы хотите сохранить пробелы в строке, вы можете удалить их непреднамеренное использование некоторых подходов. Если у вас есть этот список
[ «привет мир», «», «», «привет»] то, что вы можете [ «привет мир», «привет»]
первой обрезки список до конвертировать любой тип белого пространства пустой строки:
space_to_empty = [x.strip() for x in _text_list]
затем удалить пустую строку из них список
space_clean_list = [x for x in space_to_empty if x is not ""]
вы должны * никогда * изменить список вы итерацию. Кроме того, ваш цикл будет удалять только с начала вашего списка, как только непустая строка будет fiund. –
@Ivo, ни одно из этих утверждений не является истинным. Вы никогда не должны изменять список, в котором выполняется повторное использование с помощью 'for x in list'. Если вы используете' while loop', тогда это нормально. описанный цикл удалит пустые строки, пока не будет больше пустых строк, а затем остановится. Я на самом деле даже не рассматривал вопрос (просто название), но я ответил с помощью того же цикла, что и возможность! Если вы не хотите использовать понимание или фильтры для памяти, это очень pythonic решение. – aaronasterling
@AaronMcSmooth Вы правы, я сделал неправильные предположения о цикле, потому что я выглядел недостаточно хорошо. Мой плохой –