插入以嵌套列表

时间:2013-03-22 19:43:25

标签: python nested-lists

说我有一个像这样的嵌套列表:

nested_list=[[123,'Aaron','CA'],[124,'Bob','WY'],[125,'John','TX']]
insert_me=[122,'George','AL']

列表当前按每个子列表的中间值排序(按字母顺序排列),我想将值insert_me添加到嵌套列表中的正确位置。为了保持字母顺序,需要在列表中添加'Bob'和'John'。我知道bisect通常会用于这样的任务与列表,但不明白我如何使用bisect作为这样的嵌套列表。

3 个答案:

答案 0 :(得分:4)

请参阅bisect的Python文档中的示例:

  

与sorted()函数不同,它对bisect()没有意义   函数有关键或反向参数,因为这会导致   效率低下的设计(连续调用bisect函数不会   “记住”所有以前的键查找。)

     

相反,最好搜索预先计算的键列表来查找   有问题的记录索引:

>>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key=lambda r: r[1])
>>> keys = [r[1] for r in data]         # precomputed list of keys
>>> data[bisect_left(keys, 0)]
('black', 0)
>>> data[bisect_left(keys, 1)]
('blue', 1)
>>> data[bisect_left(keys, 5)]
('red', 5)
>>> data[bisect_left(keys, 8)]
('yellow', 8)

所以在你的情况下:

nested_list = [[123,'Aaron','CA'],[124,'Bob','WY'],[125,'John','TX']]
insert_me = [122,'George','AL']                                
keys = [r[1] for r in nested_list]
nested_list.insert(bisect.bisect_left(keys,insert_me[1]),insert_me)
[[123, 'Aaron', 'CA'],
 [124, 'Bob', 'WY'],
 [122, 'George', 'AL'],
 [125, 'John', 'TX']]

为避免每次重建keys,请将新值插入keys

keys.insert(bisect_left(keys,insert_me[1]),insert_me[1])

更新

在insert / bisect,append / sorted和heapq solutions之间进行了一些性能比较:

# elements  heapq   insert/bisect  append/sorted
10,000      0.01s   0.08s           2.43s         
20,000      0.03s   0.28s          10.06s
30,000      0.04s   0.60s          22.81s

答案 1 :(得分:3)

我会针对您的问题使用heap的专精。从this answer获取堆类,您的代码将是:

import heapq

class MyHeap(object):
    def __init__(self, initial=None, key=lambda x:x):
        self.key = key
        if initial:
            self._data = [(key(item), item) for item in initial]
            heapq.heapify(self._data)
        else:
            self._data = []

    def push(self, item):
        heapq.heappush(self._data, (self.key(item), item))

    def pop(self):
        return heapq.heappop(self._data)[1]

h = MyHeap([[123,'Aaron','CA'],[124,'Bob','WY'],[125,'John','TX']], key=lambda x:x[1])
h.push([122,'George','AL'])
for _ in xrange(4):
    print h.pop()

使用push添加的每个列表都将按顺序排列第二个元素(我们使用构造函数中的key=lambda x:x[1]参数控制)。您可以通过调用pop逐个按顺序获取元素。

答案 2 :(得分:2)

您可以使用sorted()按字母顺序排列列表。

nested_list=[[123,'Aaron','CA'],[124,'Bob','WY'],[125,'John','TX']]
insert_me=[122,'George','AL']

nested_list.append(insert_me)
nested_list=sorted(nested_list, key=lambda x:x[1])

Sorted()