Попытка удалить литерал в списке [duplicate]

Это означает, что ваш код использовал ссылочную переменную объекта, которая была установлена ​​в нуль (т. е. она не ссылалась на экземпляр фактического объекта).

Чтобы предотвратить ошибку, объекты, которые могут быть пустыми, должны быть протестированы для 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
}
492
задан zerodx 2 October 2010 в 12:21
поделиться

14 ответов

Я бы использовал 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
826
ответ дан ndmeiri 25 August 2018 в 21:20
поделиться

В зависимости от размера вашего списка это может быть наиболее эффективным, если вы используете list.remove (), а не создаете новый список:

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

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

Это имеет то преимущество, что не создает новый но недостатком является необходимость поиска с самого начала каждый раз, хотя в отличие от использования while '' in l, как было предложено выше, он требует только один раз на вхождение в '' (конечно, есть способ сохранить лучшее из обоих методов, но это сложнее).

5
ответ дан Andrew Jaffe 25 August 2018 в 21:20
поделиться

Для устранения пустых носителей после удаления:

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
    
0
ответ дан ankostis 25 August 2018 в 21:20
поделиться
>>> 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
16
ответ дан Aziz Alto 25 August 2018 в 21:20
поделиться

Пояснения к списку

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

Выход: ['first', 'second']

Редактирование: сокращено, как предлагается

154
ответ дан Elias Zamaria 25 August 2018 в 21:20
поделиться

Используйте 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

это наиболее интуитивно понятное из методов и делает это в приличное время.

5
ответ дан Forest Ka 25 August 2018 в 21:20
поделиться
Фильтр

на самом деле имеет специальную опцию для этого:

filter(None, sequence)

Он будет отфильтровывать все элементы, которые оцениваются как False. Нет необходимости использовать фактические вызываемые здесь такие, как bool, len и т. Д.

Это одинаково быстро, как map (bool, ...)

57
ответ дан Ivo van der Wijk 25 August 2018 в 21:20
поделиться

Имейте в виду, что если вы хотите сохранить пробелы внутри строки, вы можете удалить их непреднамеренно, используя некоторые подходы. Если у вас есть этот список

['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]
2
ответ дан jedema 25 August 2018 в 21:20
поделиться

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']

-3
ответ дан Mihriban Minaz 25 August 2018 в 21:20
поделиться

Как сообщается Азиз Альто 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() разделит эти строки.

4
ответ дан Paolo Melchiorre 25 August 2018 в 21:20
поделиться

Прокрутите список существующих строк и затем проверьте пустую строку, если она не пуста, заполнить новый список строк непустыми значениями и затем заменить старый список строк новым списком строк

-3
ответ дан Roland 25 August 2018 в 21:20
поделиться

Ответ от @ Ib33X замечательный. Если вы хотите удалить каждую пустую строку, после удаления. вам также нужно использовать метод полосы. В противном случае он также вернет пустую строку, если она имеет пробелы. Например, «» будет действительным и для этого ответа. Таким образом, может быть достигнуто.

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

Ответ для этого будет ["first", "second"]. Если вы хотите использовать метод filter, вы можете сделать это как list(filter(lambda item: item.strip(), strings)). Это дает тот же результат.

8
ответ дан ssi-anik 25 August 2018 в 21:20
поделиться
str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']

for item in str_list:
    if len(item) < 1:  
        str_list.remove(item)

Короткий и сладкий.

-2
ответ дан Thayne 25 August 2018 в 21:20
поделиться

Вместо 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"]
9
ответ дан thiruvenkadam 25 August 2018 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: