按第一项对嵌套列表进行排序——itemgetter 没有做到这一点

Posted

技术标签:

【中文标题】按第一项对嵌套列表进行排序——itemgetter 没有做到这一点【英文标题】:Sorting a nesting list by the first item -- itemgetter not doing the trick 【发布时间】:2012-03-15 20:37:48 【问题描述】:

我有一本已转换为列表的字典,因此我可以按第一项排序。字典中的键是一个字符串(数字),值是一个保存在列表中的整数。 字典转换的列表如下所示:

[('228055', 1), ('228054', 1), ('228057', 2), ('228056', 1), ('228051', 1), ('228050', 1),     ('228053', 1), ('203184', 6), ('228059', 1), ('228058', 1), ('89370', 2), ('89371', 3), ('89372', 2), ('89373', 1), ('89374', 1), ('89375', 1), ('89376', 1), ('89377', 1), ('89378', 1), ('89379', 1),.........]

字典中有大约 240,000 个条目。我想按第一个索引对字典进行排序,但是当我使用 itemgetter(0) 时,它首先按所有“1”对列表进行排序。排序后的列表如下所示:

[('0', 3), ('1', 3), ('10', 3), ('100', 4), ('1000', 3), ('10000', 1), ('100000', 3), ('100001', 2), ('100002', 3), ('100003', 3), ('100004', 2), ('100005', 2), ('100006', 2), ('100007', 2), ('100008', 2), ('100009', 2), ('10001', 1), ('100010', 3), ('100011', 3), ('100012', 3), ('100013', 2), ('100014', 1), ('100015', 1), ('100016', 1), ('100017', 1), ('100018', 1), ....]

我希望列表按 ['0', 3), ('1', 3), ('2', integer), ('3', integer),...('240,000 ', 整数)]

这是我的代码,我将文本文件读入字典,转换为列表并使用 itemgetter 按嵌套列表中的第一项排序。我需要代码中的字典,因为我严重依赖它来按键查找值。我只是在运行所有进程后才尝试对输出文件的字典进行排序。感谢您的帮助。

import sys, string, csv, arcpy, os, fileinput, traceback
from arcpy import env
from operator import itemgetter


#Creating a dictionary of FID: LU_Codes from external txt file
text_file = open("H:\SWAT\NC\FID_Whole_Copy.txt", "rb")
#Lines = text_file.readlines()
FID_GC_dict =  dict()
reader = csv.reader(text_file, delimiter='\t')
for line in reader:
    FID_GC_dict[line[0]] = int(line[1])
text_file.close()

dict_List = [(x, FID_GC_dict[x]) for x in FID_GC_dict.keys()]
dict_List.sort(key=itemgetter(0))
print dict_List

【问题讨论】:

text_file = open(r"H:\SWAT\NC\FID_Whole_Copy.txt") 【参考方案1】:

那是因为它们是字符串。

key=lambda x: int(x[0])

【讨论】:

你摇滚!!非常感谢! 为什么不能做 key=int(itemgetter(0))?我收到此错误:TypeError:int() 参数必须是字符串或数字,而不是“operator.itemgetter”。哦,好吧,我会使用 lambda。 @tommy.carstensen: operator.itemgetter() 返回一个函数。您不能将函数转换为整数。【参考方案2】:

更改将字符串转换为 int 的键会对您有所帮助,这里还有一些其他的排序技巧。

from operator import itemgetter

list_to_sort=[('89372', 2), ('89373', 1), ('89374', 1), ('89375', 1), ('89376', 1),     ('89377', 1), ('228055', 1), ('228054', 1), ('228057', 2), ('228056', 1), ('228051', 1), ('228050', 1),('228053', 1), ('203184', 6), ('228059', 1), ('228058', 1), ('89370', 2), ('89371', 3), ('89372', 2), ('89373', 1), ('89374', 1), ('89375', 1), ('89376', 1), ('89377', 1)]
print list_to_sort

list_to_sort.sort()
print list_to_sort # badly sorted as described

list_to_sort.sort(key=itemgetter(0))
print list_to_sort # badly sorted as described (same as above)

list_to_sort.sort(key=lambda x: int(x[0]))
print list_to_sort # sorted well

list_to_sort.sort(key=lambda x: int(x[0]), reverse=True)
print list_to_sort # sorted well in reverse

关于构建列表以从 dict 排序的旁注。 iteritems() 是一种更好的方式来执行以下操作

dict_List = [(x, FID_GC_dict[x]) for x in FID_GC_dict.keys()]

dict_List = [(k,v) for k,v in FID_GC_dict.iteritems()]

【讨论】:

请在发布之前测试您的代码;这些“提示”被打破了。您的第一行“gen_sorted=”行不通: genexp 没有 .sort() 方法。对于您的“[k, v in FID_GC_dict.iteritems()]”,语法错误——没有“for”,所以这是“[k, (v in FID_GC_dict.iteritems())] 最后两个都不是”一个已调整的“答案将起作用,因为你已经结合了你的错误。我从来没有拒绝过一个答案,但这次我很受诱惑。琳达:请不要从这个“答案”中学习 Python。@Ignacio Vazquez - 艾布拉姆斯简洁,但正确,与此不同,没有误导。 是的,我匆匆忙忙,它没有经过测试,我认为排序在列表上返回了一个可迭代的。上面不是我的笔记,答案已经完全改变。感谢帝斯曼的反馈,我会记住一些要点。 DSM 的 cmets 不再成立,答案已根据他的反馈更新和修复,测试和验证 假设你使用的是 Python 2——你必须使用 Python 3,因为 iteritems() 在 Python 3 中不存在——那么你的最后两个“更好的方式”只是冗长的编写方式FID_GC_dict.items().

以上是关于按第一项对嵌套列表进行排序——itemgetter 没有做到这一点的主要内容,如果未能解决你的问题,请参考以下文章

php根据二维数组的某一项对数组进行排序

如何按第一位数字的降序对整数数组进行排序? [关闭]

python之itemgetter函数:对字典列表进行多键排序

按第二项(整数值)对元组列表进行排序[重复]

如何按第二个单词对列表进行排序? [复制]

按第二个值对元组列表进行排序,reverse=True,然后按 key,reverse=False