2015-07-28 6 views
4

Say, у меня есть DIC, как этотВременно распаковке словарь

my_dictionary = {'a':1,'c':5,'b':20,'d':7} 

Теперь, я хочу сделать это с моим DIC:

if my_dictionary['a'] == 1 and my_dictionary['d'] == 7: 
    print my_dictionary['c'] 

Это выглядит смешно, потому что я печатаю my_dictionary 3 раза!

Так есть ли синтаксис, который позволил бы мне сделать что-то вроде этого:

within my_dictionary: 
    if a == 1 and d == 7: 
     print c 

Это на самом деле работать, если у меня не было ничего более (в данном случае б) в мой DIC:

def f(a,d,c): 
    if a == 1 and d == 7: 
     print c 

f(**my_dictionary) 
+0

Я понимаю, что словари обычно относятся к «несвязанным предметам». Но в вашем случае c связан с a и d. Должен ли быть словарь? Будете ли вы всегда искать 2 значения и возвращать третье или вы будете искать n значений? – Charlie

ответ

4

Вы можете изменить функцию

def f(a,d,c,**args): 
    if a == 1 and d == 7: 
     print c 

тогда он будет работать, даже если у вас есть другие предметы в dict.

+0

Прохладный! Я был почти там :) – Pekka

3

Вы можете использовать operator.itemgetter минимизировать несколько индексации:

>>> if operator.itemgetter('a','d')(my_dictionary)==(1,7): 
...  print operator.itemgetter('c')(my_dictionary) 

И вы можете использовать его в функции:

>>> def get_item(*args): 
... return operator.itemgetter(*args)(my_dictionary) 
... 
>>> 
>>> if get_item('a','d')==(1,7): 
...  print get_item('c') 
... 
5 
2

Чтобы ответить

Так есть ли синтаксис, который позволил бы мне сделать что-то вроде этого:

within my_dictionary: 
if a == 1 and d == 7: 
    print c 

Вы можете подклассифицировать так, чтобы у него были with магические методы. Для этого класс должен иметь методы __enter__ и __exit__. Затем вы можете экспортировать ключи в локальную область оператора with и очистить их с помощью метода exit.

Использование this answer Я был в состоянии создать подкласс, который сделал так:

import inspect 
import ctypes 

locals_to_fast = ctypes.pythonapi.PyFrame_LocalsToFast 
locals_to_fast.restype = None 
locals_to_fast.argtypes = [ctypes.py_object, ctypes.c_int] 

class WithDict(dict): 
    def __enter__(self): 
     frame = self.get_frame() 
     for k,v in self.iteritems(): 
      frame.f_locals[str(k)] = v 
      locals_to_fast(frame, 1) 

    def __exit__(self, exc_type, exc_value, traceback): 
     frame = self.get_frame() 
     for k in self.keys(): 
      del frame.f_locals[str(k)] 

    def get_frame(self): 
     return inspect.getouterframes(inspect.currentframe())[2][0] 

тестовый пример, используя ваш оригинальный пример

my_dictionary = WithDict({'a':1,'c':5,'b':20,'d':7}) 
with my_dictionary: 
    if a == 1 and d == 7: 
     print c 

печатает 5

переменные удаляются, когда with Заявление завершено

+0

Спасибо! Это очень полезная информация. Я не знаком с 'with',' __exit__' и '__enter__', и для моей конкретной проблемы это, вероятно, слишком сильно напоминает убийство пчел с ядерными ракетами. Тем не менее, похоже, мне нужно взглянуть. – Pekka

+0

Да, я думал, что, когда я писал это, все равно было отличным экстерсисом. Вы могли бы сделать это (даже больше?) Неприятным путем обезглавливания 'dict' и использования манипуляции с байт-кодом, чтобы вы могли буквально использовать синтаксис {}, но это действительно было бы похоже на использование ядер! – muddyfish

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

  • Нет связанных вопросов^_^