2009-08-01 114 views
28

仍在学习Python(终于!),并不能完全包围我的头。我想要做的是使用列表中的第三项按值排序字典。当值只是单个数字或字符串时,很容易按值排序字典,但这个列表让我感到困惑。Python:排序列表字典

实施例:

myDict = { 'item1' : [ 7, 1, 9], 'item2' : [8, 2, 3], 'item3' : [ 9, 3, 11 ] } 

我希望能够通过在字典中的每个列表中的第三值的顺序来遍历,在这种情况下如图9所示,3,11

感谢任何帮帮我!

回答

33

下面是做到这一点的一种方法:

>>> sorted(myDict.items(), key=lambda e: e[1][2]) 
[('item2', [8, 2, 3]), ('item1', [7, 1, 9]), ('item3', [9, 3, 11])] 

sorted功能的key argument,您可以得出列表中的每个元素的排序键。

遍历键/值在这份名单中,你可以使用类似:

>>> for key, value in sorted(myDict.items(), key=lambda e: e[1][2]): 
... print key, value 
... 
item2 [8, 2, 3] 
item1 [7, 1, 9] 
item3 [9, 3, 11] 
+1

只要我问这个问题,我有一个顿悟,基本上提出了除lambda之外的相同的东西(还没有了解它们)。刚刚写了我自己的cmp函数,它接收来自dict.items()的图簇并返回结果。同样的事情,只是写它的一种不同的方式。非常感谢您的快速回复! – jay 2009-08-01 19:21:43

+0

伟大的解决方案。我喜欢sort()的简单性。 – 2009-08-01 19:24:38

2

你说两个完全不同的希望:

  1. “我想要做的是不大不小的名单的字典...”
  2. ‘我希望能够通过字典中的顺序来遍历......’

其中的第一个根据定义是不可能的 - 排序的东西意味着以某种顺序重新排列。 Python词典本质上是无序的。第二种可能会有些模糊,但极不可能实施。

你可以做的是

  1. 采取的词典内容的副本(这将是相当 无序)
  2. 那种
  3. 遍历排序结果 - 你已经有两个 解决方案。顺便说一下,使用“cmp”的“key”代替 的解决方案更好;看到sorted

“在列表中的第三项”闻起来像我“在一个元组的第三项”和“e [1] [2]”只闻:-) ......你可能会喜欢调查使用命名元组而不是列表;看到named tuple factory

如果你将要在大型数据集往往做提取/排序/过程中,你可能要考虑这样的事情,使用Python提供的sqlite3的模块:

create table ex_dict (k text primary key, v0 int, v1 int, v2 int); 
insert into ex_dict values('item1', 7, 1, 9); 
-- etc etc 
select * from ex_dict order by v2; 
2

正如约翰Machlin说你实际上不能对Python字典进行排序。

但是,您可以创建可按您喜欢的任何顺序排序的键索引。

用于通过任何备选标准进行排序的首选Python模式(成语)称为“装饰排序undecorate”(DSU)。在这个习惯用法中,你创建了一个临时表,其中包含你的密钥的元组,然后是原始数据元素,然后在该列表上调用正常的.sort()方法(或者在更新版本的Python中简单地包装装修中一个叫排序()内置功能)。然后你删除“装饰品”。

这通常优于使比较函数到的.sort()方法是其原因Python的内置的默认排序代码(在正常的C的Python编译C)是在默认情况下非常快速和有效,但是在非默认情况下需要多次调用Python对象代码时,速度要慢得多。因此,迭代数据创建数据结构通常要好得多,这些数据结构可以传递给默认排序例程。

在这种情况下,你应该能够使用类似:

[y[1] for y in sorted([(myDict[x][2], x) for x in myDict.keys()])] 

...这是一个列表理解这样做从正由内部列表理解返回的元组的排序列表中去除装饰。内部理解是创建一组元组,您想要的排序键(列表的第三个元素)以及与排序键相对应的字典键。 myDict.keys()当然是Python字典的一种方法,它以任何顺序返回所有有效密钥的列表,底层实现选择 - 大概是对哈希的简单迭代。

这样做可能是更容易的更详细的方式来阅读:

temp = list() 
for k, v in myDict.items(): 
    temp.append((v[2],)) 
temp.sort() 
results = list() 
for i in temp: 
    results.append(i[1]) 

通常你应该使用小数据样本反复建立这样的代码,在解释。构建“装饰”表达式或函数。然后在打电话给排序()。然后建立undecorate表达式(通常与我在这里展示的一样简单)。