2017-01-24 3 views
0

У меня есть список словарей, например, так:Продувочные пустые словари из списка словаря

[{'a':'21'},{},{'b':20'},{'c':'89'},{}] 

Что наиболее эффективный способ очистить пустые словари из этого списка, конечный результат являются:

[{'a':'21'},{'b':'20'},{'c':'89'}] 

пытаюсь:

new_list_of_dictionaries = [] 
for dictionary in list_of_dictionaries: 
    if dictionary: 
     new_list_of_dictionaries.append(dictionary) 
return new_list_of_dictionaries 

Я не думаю, что это можно сделать в O (1) или что-то еще?

+0

Как Вы в итоге оказались с пустыми словарями? Вероятно, вы можете создать список без них. –

+0

Я думаю, что теперь я видел этот точный вопрос для строк, списков, словарей и кортежей - понятно, потому что люди не делают ту же проблему для другой структуры. Интересно, что будет next :) – miradulo

+0

@ MartijnPieters ♦: Исправьте меня, если я ошибаюсь, но 'filter' - это то же самое, что использовать понимание списка с точки зрения сложности времени. Он просто читает по-другому. Да? –

ответ

6

Просто используйте понимание списка и фильтруйте по логической истине. Пустой словарь считается ложным:

return [d for d in list_of_dictionaries if d] 

В Python 2, вы можете также использовать filter() function, используя None в качестве фильтра:

return filter(None, list_of_dictionaries) 

В Python 3, который возвращает итератор, а не список, поэтому вам нужно будет позвонить list() по этому поводу (так return list(filter(None, ...))), после чего понимание списка просто читаемо. Конечно, если вам действительно не нужен случайный доступ к результату (поэтому прямой доступ к индексу до result[whatever]), то итератор все равно может быть хорошей идеей.

Обратите внимание, что это имеет, чтобы взять время O (N), вам нужно проверить каждый словарь. Даже если в списках была какая-то автоматическая обновленная карта, которая позволяет вам получить индексы словарей, которые пусты в O (1), удаление элементов из списка требует переноса последующих записей вперед.

3

может использовать список?

myList = [{'a':'21'},{},{'b':'20'},{'c':'89'},{}] 

result = [x for x in myList if x] 
4

Постижение или filter (Python2, Python3):

return filter(None, list_of_dictionaries) 

# Python3, if you prefer a list over an iterator 
return list(filter(None, list_of_dictionaries)) 

None, как функция фильтра будет отфильтровывать все без truthy элементы, которые в случае пустых коллекций делает его весьма кратким.

+0

@MartijnPieters Правда, добавлено уточнение. – schwobaseggl

-2

Я сделал это таким образом

d = [{'a': '21'}, {}, {'b': 20}, {'c': '89'}, {}] 
new_d = [] 
for item in d: 
    check = bool(item) 
    if not check: 
     del item 
    else: 
     new_d.append(item) 

print(new_d) 

[{ 'а': '21'}, { 'Ь': 20}, { 'с': '89'}]

+0

Элемент 'del item 'является полностью избыточным. Создание нового списка, как это, происходит медленнее, чем понимание списка, поскольку вы несете 'new_d.append', каждый раз, а также стоимость стека кадров для вызова метода. –

+0

Вызов 'bool()' полностью избыточен, потому что это то, что 'if' и' not' do * уже *. Это просто занятые, дополнительные циклы, которыми вы могли бы обойтись. –

+0

да, вы правы –

Смежные вопросы