临时解压字典
Temporarily unpack dictionary
说,我有这样的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 中没有更多内容(在本例中为 b),这实际上会起作用:
def f(a,d,c):
if a == 1 and d == 7:
print c
f(**my_dictionary)
您可以将函数更改为
def f(a,d,c,**args):
if a == 1 and d == 7:
print c
即使字典中有其他项目,它也能正常工作。
您可以使用 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
回答
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
您可以子class dict 使其具有with
魔术方法。为此,class 必须具有 __enter__
和 __exit__
方法。然后,您可以将密钥导出到 with 语句的本地范围,并使用 exit 方法清除它们。
使用 this answer 我能够创建一个这样做的子class:
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
语句完成后变量被删除
说,我有这样的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 中没有更多内容(在本例中为 b),这实际上会起作用:
def f(a,d,c):
if a == 1 and d == 7:
print c
f(**my_dictionary)
您可以将函数更改为
def f(a,d,c,**args):
if a == 1 and d == 7:
print c
即使字典中有其他项目,它也能正常工作。
您可以使用 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
回答
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
您可以子class dict 使其具有with
魔术方法。为此,class 必须具有 __enter__
和 __exit__
方法。然后,您可以将密钥导出到 with 语句的本地范围,并使用 exit 方法清除它们。
使用 this answer 我能够创建一个这样做的子class:
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
语句完成后变量被删除