Это означает, что ваш код использовал ссылочную переменную объекта, которая была установлена в нуль (т. е. она не ссылалась на экземпляр фактического объекта).
Чтобы предотвратить ошибку, объекты, которые могут быть пустыми, должны быть протестированы для null перед тем, как использовать.
if (myvar != null)
{
// Go ahead and use myvar
myvar.property = ...
}
else
{
// Whoops! myvar is null and cannot be used without first
// assigning it to an instance reference
// Attempting to use myvar here will result in NullReferenceException
}
Я бы использовал 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
В зависимости от размера вашего списка это может быть наиболее эффективным, если вы используете list.remove (), а не создаете новый список:
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
Это имеет то преимущество, что не создает новый но недостатком является необходимость поиска с самого начала каждый раз, хотя в отличие от использования while '' in l
, как было предложено выше, он требует только один раз на вхождение в ''
(конечно, есть способ сохранить лучшее из обоих методов, но это сложнее).
Для устранения пустых носителей после удаления:
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
>>> 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
strings = ["first", "", "second"]
[x for x in strings if x]
Выход: ['first', 'second']
Редактирование: сокращено, как предлагается
Используйте 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
это наиболее интуитивно понятное из методов и делает это в приличное время.
на самом деле имеет специальную опцию для этого:
filter(None, sequence)
Он будет отфильтровывать все элементы, которые оцениваются как False. Нет необходимости использовать фактические вызываемые здесь такие, как bool, len и т. Д.
Это одинаково быстро, как map (bool, ...)
Имейте в виду, что если вы хотите сохранить пробелы внутри строки, вы можете удалить их непреднамеренно, используя некоторые подходы. Если у вас есть этот список
['hello world', '', '', 'hello'], что вы можете захотеть ['hello world', 'hello']
first обрезать список, чтобы преобразовать любой тип пробела в пустую строку:
space_to_empty = [x.strip() for x in _text_list]
затем удалить пустую строку из их списка
space_clean_list = [x for x in space_to_empty if x]
filter(None, str)
не удаляет пустые строки с пробелом '', это только сокращает '' и ''.
join(str).split()
удаляет оба. но если ваш элемент списка имеет пространство, то он изменит элементы списка также потому, что он соединяет сначала все ваши элементы списка, а затем выплевывает их по пространству, поэтому вы должны использовать: -
str = ['hello', '', ' ', 'world', ' ']
print filter(lambda x:x != '', filter(lambda x:x != ' ', str))
Он удалит оба и не будет влиять на ваши элементы. Like: -
str = ['hello', '', ' ', 'world ram', ' ']
print ' '.join(lstr).split()
print filter(lambda x:x != '', filter(lambda x:x != ' ', lstr))
output: -
['hello', 'world', 'ram'] & lt; ---- ---------- вывод ' '.join(lstr).split()
['hello', 'world ram']
Как сообщается Азиз Альто filter(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()
разделит эти строки.
Прокрутите список существующих строк и затем проверьте пустую строку, если она не пуста, заполнить новый список строк непустыми значениями и затем заменить старый список строк новым списком строк
Ответ от @ Ib33X замечательный. Если вы хотите удалить каждую пустую строку, после удаления. вам также нужно использовать метод полосы. В противном случае он также вернет пустую строку, если она имеет пробелы. Например, «» будет действительным и для этого ответа. Таким образом, может быть достигнуто.
strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
Ответ для этого будет ["first", "second"]
. Если вы хотите использовать метод filter
, вы можете сделать это как list(filter(lambda item: item.strip(), strings))
. Это дает тот же результат.
str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']
for item in str_list:
if len(item) < 1:
str_list.remove(item)
Короткий и сладкий.
Вместо 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"]