Temporarily unpack dictionary

岁酱吖の 提交于 2019-12-06 05:43:18

问题


Say, I have a dic like this

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

Now, I want to do this with my dic:

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

This looks ridiculous because I am typing my_dictionary 3 times!

So is there any syntax which would allow me to do something like this:

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

This would actually work if I didn't have anything more (in this case b) in my dic:

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

f(**my_dictionary)

回答1:


You can change your function to

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

then it will work even if you have other items in the dict.




回答2:


You can use operator.itemgetter to minimize multiple indexing :

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

And you can use it in a function :

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



回答3:


To answer

So is there any syntax which would allow me to do something like this:

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

You can subclass dict so that it has with magic methods. To do this, the class must have __enter__ and __exit__ methods. You could then export the keys to the local scope of the with statement and clean them up with the exit method.

Using this answer I was able to create a subclass that did so:

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]

A test case using your original example

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

prints 5

The variables get deleted when the with statement completes



来源:https://stackoverflow.com/questions/31675756/temporarily-unpack-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!