Подтвердить что ты не робот

Один лайнер, чтобы определить, являются ли значения словаря пустыми списками или нет

У меня есть dict следующим образом:

someDict = {'a':[], 'b':[]}

Я хочу определить, есть ли в этом словаре какие-либо значения, которые не являются пустыми списками. Если это так, я хочу вернуть True. Если нет, я хочу вернуть False. Любой способ сделать это одним лайнером?

4b9b3361

Ответ 1

В моем тестировании следующий однострочный (мой оригинальный ответ) имеет наилучшую производительность во всех сценариях. См. Правки ниже для тестирования информации. Я действительно признаю, что решения с использованием выражений генератора будут гораздо более эффективными с точки зрения памяти и должны быть предпочтительными для больших dicts.

EDIT: это стареющий ответ, и результаты моего тестирования могут быть неверными для последней версии python. Поскольку выражения генератора являются более "питоническими", я бы предположил, что их производительность улучшается. Пожалуйста, сделайте собственное тестирование, если вы используете это в "горячей" кодировке.

bool([a for a in my_dict.values() if a != []])

Edit:

Решил немного повеселиться. Сравнение ответов не в каком-либо конкретном порядке:

(Как используется ниже, timeit будет вычислять порядок циклов на основе того, что займет менее 0,2 секунды)

bool ([a для a в my_dict.values ​​(), если a!= []]):

python -mtimeit -s"my_dict={'a':[],'b':[]}" "bool([a for a in my_dict.values() if a != []])"
1000000 loops, best of 3: 0.875 usec per loop

any ([my_dict [i]!= [] для я в my_dict]):

python -mtimeit -s"my_dict={'a':[],'b':[]}" "any([my_dict[i] != [] for i in my_dict])"
1000000 loops, best of 3: 0.821 usec per loop

any (x!= [] для x в my_dict.itervalues ​​()):

python -mtimeit -s"my_dict={'a':[],'b':[]}" "any(x != [] for x in my_dict.itervalues())"
1000000 loops, best of 3: 1.03 usec per loop

all (map (lambda x: x == [], my_dict.values ​​())):

python -mtimeit -s"my_dict={'a':[],'b':[]}" "all(map(lambda x: x == [], my_dict.values()))"
1000000 loops, best of 3: 1.47 usec per loop

filter (lambda x: x!= [], my_dict.values ​​()):

python -mtimeit -s"my_dict={'a':[],'b':[]}" "filter(lambda x: x != [], my_dict.values())"
1000000 loops, best of 3: 1.19 usec per loop



Изменить снова - веселее:

any() - лучший пример O (1) (если bool (list [0]) возвращает True). any() наихудший случай - это "положительный" сценарий - длинный список значений, для которых bool (list [i]) возвращает False.


Посмотрите, что происходит, когда дикт становится большим:

bool ([a для a в my_dict.values ​​(), если a!= []]):

#n=1000
python -mtimeit -s"my_dict=dict(zip(range(1000),[[]]*1000))" "bool([a for a in my_dict.values() if a != []])"
10000 loops, best of 3: 126 usec per loop

#n=100000
python -mtimeit -s"my_dict=dict(zip(range(100000),[[]]*100000))" "bool([a for a in my_dict.values() if a != []])"
100 loops, best of 3: 14.2 msec per loop

any ([my_dict [i]!= [] для я в my_dict]):

#n=1000
python -mtimeit -s"my_dict=dict(zip(range(1000),[[]]*1000))" "any([my_dict[i] != [] for i in my_dict])"
10000 loops, best of 3: 198 usec per loop

#n=100000
python -mtimeit -s"my_dict=dict(zip(range(100000),[[]]*100000))" "any([my_dict[i] != [] for i in my_dict])"
10 loops, best of 3: 21.1 msec per loop



Но этого недостаточно - как насчет сценария "False" в худшем случае?

bool ([a для a в my_dict.values ​​(), если a!= []]):

python -mtimeit -s"my_dict=dict(zip(range(1000),[0]*1000))" "bool([a for a in my_dict.values() if a != []])"
10000 loops, best of 3: 198 usec per loop

any ([my_dict [i]!= [] для я в my_dict]):

python -mtimeit -s"my_dict=dict(zip(range(1000),[0]*1000))" "any([my_dict[i] != [] for i in my_dict])"
1000 loops, best of 3: 265 usec per loop

Ответ 2

Не сбрасывать или не пустые списки:

Не falsey:

any(someDict.values())

Не пустые списки:

any(a != [] for a in someDict.values())

или

any(map(lambda x: x != [], someDict.values()))

Или, если вы в порядке с возвращаемым значением false:

filter(lambda x: x != [], someDict.values())

Возвращает список элементов, которые не являются пустым списком, поэтому, если все они пустые списки, это пустой список:)

Ответ 3

Довольно буквально:

any(x != [] for x in someDict.itervalues())

Ответ 4

попробуйте это

 all([d[i] == [] for i in d])

edit: oops, я думаю, что вернул вас назад. позволяет deMorgan, что

any([d[i] != [] for i in d])

этот второй способ имеет преимущество короткого замыкания на первом в любом случае

Ответ 5

len(filter(lambda x: x!=[], someDict.values())) != 0

Ответ 6

>>> someDict = {'a':[], 'b':[]} 
>>> all(map(lambda x: x == [], someDict.values()))
True