Pythonic方法获取字典中的所有元素,落在两个键之间?

时间:2011-12-28 10:25:46

标签: python

我有一个字典对象,我想提取字典的一个子集(即返回另一个字典),其中包含密钥与特定条件匹配的父字典的所有元素。

例如:

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方法是什么

为了简单起见,我将标准限制为简单的布尔运算。

[[编辑]]

这是我尝试以下命令时的输出:

>>> {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

BTW,我正在运行Python 2.6.5

3 个答案:

答案 0 :(得分:4)

<强>解决方案

从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理解替换为:

dict((k,v) for k,v in parent_dict.iteritems() if 2 < k < 4)

为什么要使用lambda函数?

Lambda函数不是魔术,它只是一种轻松创建动态的方法。你可以用lambda做你所做的一切,唯一的区别是lambdas是表达式,因此可以在parenthis之间直接使用。

比较

>>> 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:。没什么了不起的,只是语法
  • 你不能制作2行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是有用的。

答案 1 :(得分:3)

dict((k,v) for k,v in parent_dict.iteritems() if 2 < k < 4)

这适用于Python 2.6.5。

答案 2 :(得分:1)

for python 2.5.2:

dict( (k,v) for k,v in parent_dict.iteritems() if k > 2 and k < 4 )