2010-07-12 118 views
20

我刚刚了解了列表理解,这是一种快速获取单行代码数据的方法。但有些东西在扰乱我。Python列表词典中的词典的理解?

在我的测试中,我有这样的词典列表里面:

[{'y': 72, 'x': 94, 'fname': 'test1420'}, {'y': 72, 'x': 94, 'fname': 'test277'}] 

列表内涵s = [ r for r in list if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ]完美的作品上(这是,事实上,这条线的结果)

不管怎么说,然后我意识到我没有真正在我的其他项目中使用列表,我正在使用字典。像这样:

{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'}} 

这样我可以简单的编辑我的字典,var['test1420'] = ...

但列表内涵不上工作! 而我无法以这种方式编辑列表,因为您无法指定这样的索引。

还有别的办法吗?

+1

列表解析可以很酷,但不要过度。对巨大的理解没有坚定的规则,但是对于它的价值,Google的Python风格指南建议不要过分复杂:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=List_Comprehensions#List_Comprehensions – 2010-07-12 21:06:17

回答

36

你可以这样做:

s = dict([ (k,r) for k,r in mydict.iteritems() if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ]) 

这需要你指定的字典,并返回一个“过滤”字典。

+0

与Tryptich的解决方案的工作方式相同,但使用iteritems的确速度更快。谢谢! – skerit 2010-07-12 22:33:11

+0

如果你把'[]'变成'()',你可以使这更快,因为字典可以把一个生成器作为参数(如果生成器表达式是唯一的参数,就像在这种情况下,甚至'()'都可以遗漏) – 2011-03-08 10:17:37

8

如果dct

{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'}, 
'test277': {'y': 72, 'x': 94, 'fname': 'test277'},} 

也许你正在寻找的东西,如:

[ subdct for key,subdct in dct.iteritems() 
    if 92<subdct['x']<95 and 70<subdct['y']<75 ] 

有点精密是Python允许您链不平等:

92<dct[key]['x']<95 

代替

if r['x'] > 92 and r['x'] < 95 

另请注意,上面我写了一个列表理解,所以你找回列表(在这种情况下,字典)。

在Python3有这样的事情dict comprehensions还有:

{ n: n*n for n in range(5) } # dict comprehension 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 

在Python2相当于将

dict((n,n*n) for n in range(5)) 

我不知道,如果你正在寻找类型的字典或列表一个口号的字典,但如果你了解上面的例子,很容易修改我的答案,以得到你想要的。

0

您可以通过d.values()获得字典d的值列表。你的列表理解应该使用这个,尽管我有点不清楚你想要输出的是什么。

2

听起来像是你想要的东西,如:

my_dict = {'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'}, 
      'test277' : {'y': '072', 'x': '094', 'fname': 'test277'}} 


new_dict = dict((k,v) for k,v in my_dict.items() 
        if 92 < int(v['x']) < 95 and 70 < int(v['y']) < 75) 

这个代码的一些注意事项:

  1. 我使用生成器表达式 ,而不是一个列表理解
  2. 利用Python可以结合不等式 测试为low < value < high
  3. dict()构造函数需要一个迭代器 键/值元组创建一个 字典
+0

这工作,看起来,像adamk的解决方案一样。然而,使用iteritems比这个更快。 这两个呃比普通列表的理解慢,但:P 感谢您的组合提示! – skerit 2010-07-12 22:32:44

0

有没有另一种方式?

为什么不考虑使用一些轻量级对象?

您可以仍然使用列表解析来收集或过滤对象,并获得很多的清晰度/可扩展性。

>>> class Item(object): 
...  def __init__(self, x, y, name): 
...   self.x = x 
...   self.y = y 
...   self.name = name 
... 
>>> list_items = [] 
>>> list_items.append(Item(x=70, y=60, name='test1420'))       
>>> list_items.append(Item(x=94, y=72, name='test277'))       
>>> items_matching = [item for item in list_items 
         if 92 < item.x < 95 and 70 < item.y < 75] 
>>> for item in items_matching: 
...  print item.name 
... 
test277 
>>> first_item = items_matching[0] 
>>> first_item.x += 50 
>>> first_item.x 
144