按第一项对嵌套列表进行排序——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 没有做到这一点的主要内容,如果未能解决你的问题,请参考以下文章