我有一个字典对象,我想提取字典的一个子集(即返回另一个字典),其中包含父字典的所有元素,其中键符合特定条件。
例如:
parent_dict = {1: 'Homer',
2: 'Bart',
3: 'Lisa',
4: 'Marge',
5: 'Maggie'
}
def filter_func(somedict, key_criteria_func):
pass
我想写(以 pythonic 方式)filter_func
,这样我就可以这样调用它:
filter_func(parent_dict, ">2 and <4")
这将返回新的字典:
{ 3: 'Lisa' }
编写 filter_func 的最 Pythonic 方式是什么?
为简单起见,我将标准限制为简单的 bool 运算。
[[编辑]]
这是我尝试以下命令时的输出:
>>> {key:val for key,val in parent_dict.iteritems() if 2 < key < 4 }
File "<stdin>", line 1
{key:val for key,val in parent_dict.iteritems() if 2 < key < 4 }
^
SyntaxError: invalid syntax
顺便说一句,我正在运行 Python 2.6.5
最佳答案
解决方案
从 python 2.7 开始,你可以使用字典理解。有类似的列表理解,但应用于字典:
>>> parent_dict = {1: 'Homer',
... 2: 'Bart',
... 3: 'Lisa',
... 4: 'Marge',
... 5: 'Maggie'
... }
>>> {key:val for key,val in parent_dict.iteritems() if 2 < key < 4 }
1: {3: 'Lisa'}
你可能不需要把它变成一个函数,但如果你这样做,你可以只使用 lambda 函数作为过滤器:
>>> def filter_func(somedict, key_criteria_func):
... return {k:v for k, v in somedict.iteritems() if key_criteria_func(k)}
...
... filter_func(parent_dict, lambda x: 2 < x < 4)
2: {3: 'Lisa'}
对于 Python 2.6.5 和 2.7 之前的所有版本,将字典理解替换为:
dict((k,v) for k,v in parent_dict.iteritems() if 2 < k < 4)
为什么要使用 lambda 函数?
Lambda 函数并不神奇,它只是一种轻松即时创建函数的方法。你可以用 lambda
做所有你做的事情,唯一的区别是 lambda 是表达式,因此可以直接在括号之间使用。
比较:
>>> func = lambda x: 2 < x < 4
>>> func(3)
True
与:
>>> def func(x):
... return 2 < x < 4
...
>>> func(3)
True
它完全相同并产生相同的函数,只是 lambda 函数没有名称。但你不在乎,在你的情况下你不需要一个名字,你只需要一个引用来调用它,变量 func
包含这个引用。
lambda 语法很奇怪,因为:
- 你不需要参数的括号(你甚至不需要参数)
- 你不做
def var(param):
但var = lambda param:
。没什么神奇的,这只是语法 - 你不能写两行
lambda
:返回结果必须适合一条指令。 - 您不使用
return
关键字:lambda 的正确部分会自动返回
lamda 的好处在于,因为它是一个表达式,所以您可以在括号之间使用它,这意味着您可以同时创建和传递您的函数。
比较:
>>> filter_func(parent_dict, lambda x: 2 < x < 4)
与:
>>> def func(x):
... return 2 < x < 4
...
>>> filter_func(parent_dict, func)
完全一样。 lambda 只是更短。
这里困难的部分是理解您可以在 Python 中将函数作为参数传递,因为 Python 中的一切都是对象,包括函数。
你甚至可以这样做:
>>> def func():
... print "test"
...
>>> ref_to_func = func # assign the function refence to another var
>>> del func # delete this label
>>> ref_to_func() # call the function from this label
test
你甚至可以在一行中定义一个函数:
>>> def func(): print "test"
>>> func()
test
但是你不能这样做:
filter_func(parent_dict, def func(x): 2 < x 4 )
这就是 lambda 的用武之地。
关于获取字典中所有元素的 Pythonic 方法,落在两个键之间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8654637/