Понимание словаря Python

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

Функция в поисковом словаре вернет пару ключ-значение, которую необходимо «обновить» в новый словарь. Итак, вот пример:

out = {getattr(self,self.LOOKUPDICT[k])({k:query[k]}) for k in query.keys() if k not in self.exclusions}

Результат

getattr(self,self.LOOKUPDICT[k])({k:query[k]}) 

Словарь, который выглядит так:

{'new_key':'new_val'}

В понимании я получаю

TypeError: unhashable type: 'dict'

Потому что он ожидает пару ключ-значение.

Теперь я могу просто запустить обычный цикл и оператор if, но я стал против них. Любое обходное решение здесь?

TLDR: понимание словаря, как вставить словарь следующим образом:

{{'k':'v'} for k in blahblah}

и сделайте k ключом, а v значением. Обратите внимание, что dict возвращается из функции, которая запускается в выражении.


person nick_v1    schedule 23.06.2015    source источник
comment
У вас есть понимание набора; у вас есть только одно выражение, а не пары ключ-значение. Какое выражение дает ключ и что здесь дает значение?   -  person Martijn Pieters    schedule 24.06.2015


Ответы (2)


Понимание словаря предполагает отдельные выражения key и value:

{key_expr: value_expr for iterable [more if and for parts]}

но если ваша функция производит и то, и другое, вам лучше использовать функцию dict() с циклом:

out = dict(getattr(self, self.LOOKUPDICT[k])({k: query[k]})
           for k in query if k not in self.exclusions)

потому что эта функция принимает последовательность кортежей, каждый из которых содержит пару ключ-значение.

Обратите внимание, что вызов .keys() здесь не нужен; итерации непосредственно над query достаточно, чтобы получить ключи. Вместо этого вы можете использовать установленные пересечения; объект dict.keys() представляет собой представление словаря, которое само действует как набор:

out = dict(getattr(self, self.LOOKUPDICT[k])({k: query[k]})
           for k in query.keys() - self.exclusions)

где выражение query.keys() - self.exclusions создает набор ключей, которые находятся в query, но не в итерируемом (набор, словарь, список, кортеж и т. д.) self.exclusions.

Если значения self.LOOKUPDICT сопоставляются с атрибутами self, может быть полезно напрямую обратиться к словарю экземпляра с помощью:

attrs = vars(self)
out = dict(attrs[self.LOOKUPDICT[k]]({k: query[k]})
           for k in query.keys() - self.exclusions)
person Martijn Pieters    schedule 23.06.2015
comment
Я согласен, что .keys() почти никогда не нужен, но иногда это помогает, когда явное лучше, чем неявное. - person Pete Cacioppi; 24.06.2015
comment
@PeteCacioppi: он создает дополнительный объект, который вам не нужен, и по этой причине руководство по стилю Python (а также руководство по стилю Google) не рекомендует его использовать. - person Martijn Pieters; 24.06.2015
comment
@PeteCacioppi: в Python 2 он создает новый объект списка, содержащий все ключи, что при использовании только для итерации еще более излишне. - person Martijn Pieters; 24.06.2015
comment
@PeteCacioppi: последнее, но не менее важное: документация типа dict явно документирует iter(d) . - person Martijn Pieters; 24.06.2015
comment
да да и да. но руководство по стилю также говорит, что я просто гид. Мы не говорим о злоупотреблении соглашениями о себе и подчеркивании, просто сопоставляем ненужное время вычислений с удобочитаемостью для ожидаемой аудитории. - person Pete Cacioppi; 24.06.2015
comment
@PeteCacioppi: ожидаемая аудитория здесь включает новичков в Python, которые будут делать ошибку, используя for key in dictionary.keys(): в Python 2 снова и снова. Это важно, вы должны всегда использовать for key in dictionary:. - person Martijn Pieters; 24.06.2015
comment
Для меня это была незавершенная работа, я собирался почистить ее позже, обещаю ;) Ключи также помогают идентифицировать ее как диктовку, поэтому, когда я смотрю на нее, мне не нужно возвращаться в код и выяснить, что это такое. - person nick_v1; 24.06.2015
comment
Спасибо, чувак, это довольно круто. Я должен был сам до этого додуматься... - person nick_v1; 24.06.2015
comment
Ключи также помогают идентифицировать его как словарь, поэтому, когда я смотрю на него, мне не нужно возвращаться в код и выяснять, что это такое. Я думаю, это разумно. - person Pete Cacioppi; 24.06.2015

как насчет этого

out = {_k:_v for k in query.keys() for _k,_v in getattr(self,self.LOOKUPDICT[k])({k:query[k]}).items() if k not in self.exclusions}

хотя это, вероятно, больше того, что вам нужно

out = {_k:_v for k in set(query.keys()).difference(self.exclusions) for _k,_v in getattr(self,self.LOOKUPDICT[k])({k:query[k]}).items()}

второй лучше, потому что он не будет выполнять вызов getattr(self,self.LOOKUPDICT[k])({k:query[k]}) для exclusions

person Pete Cacioppi    schedule 23.06.2015