我正在读取一个文件,并在Python中提取包含一些字符串和一些数字的数据。我将这些信息存储为列表列表,如下所示:
dataList = [
['blah', 2, 3, 4],
['blahs', 6, 7, 8],
['blaher', 10, 11, 12],
]
我想保持dataList按子列表的第二个元素排序:dataList [] [1]
我想我可以在我想要添加它们时使用insort或bisect,但是我无法弄清楚如何让它看到子列表的第二个元素。
有什么想法吗?我只是将数据附加到最后,然后进行线性排序以便稍后查找。但是,在这里扔几千个子列表,然后搜索10万个项目,这需要一段时间。
答案 0 :(得分:8)
dataList.sort(key=lambda x: x[1])
这会按照每个项目中的第二个元素对列表进行排序。
正如评论中指出的那样,只排序一次(最后)效率更高。 Python的内置排序方法已经过大幅优化,可以快速工作。经过测试,看起来内置排序的速度始终比使用其他答案中建议的heap method快了大约3.7倍,而不是各种大小的列表(我测试的大小最多为600000)。
答案 1 :(得分:7)
取决于一些事情,但首先想到的是使用heapq模块:
import heapq
heap = []
for row in rows:
heapq.heappush(heap, (row[1], row))
这将创建一个充满元组的堆,其中第一个元素是您要排序的元素,第二个元素是行。
从堆中读取它们的最简单方法是复制它然后弹出项目:
new_heap = list(heap)
while new_heap:
_, row = heapq.heappop(new_heap)
print row
将每个项目插入堆中的运行时为O(lg N)
,因此创建堆将需要O(N lg N)
时间,并且从堆中弹出项目也需要O(lg N)
时间,因此{{ 1}}将需要时间来遍历它。
如果这些权衡不理想,您可以使用二叉搜索树(标准库中不存在,但是they are easy to find),或者像其他评论者建议的那样,在阅读后对行进行排序:{{1 }}
现在,在实践中,除非您处理的行数非常多,否则在加载后对列表进行排序几乎肯定会更快(即使用O(N lg N)
方法)...所以尝试一些事情,看看哪种方法最有效。
最后,rows.sort(key=lambda row: row[1])
是一个糟糕的主意,因为插入Python列表需要.sort()
时间,因此插入带有bisect的项目需要bisect
时间每个项目 ,所以总时间为O(N)
。