Python - 在保持顺序的情况下将元素添加到字典列表中

3

我有一个Python列表,其中包含个人信息的字典,如下所示:

entries = [
    {
        "first_name": "philip",
        "last_name": "fry"
    },
    {
        "first_name": "john",
        "last_name": "zoidberg"
    }
]

我希望能够按照升序(姓氏,名字)的方式添加项目到此列表中。Bisect模块似乎很有希望,但它好像不支持这一点。
非常感谢您的帮助!

blist 包提供了一个 sortedlist 类型,可能会很有用。 - BrenBarn
https://docs.python.org/2/library/collections.html#collections.OrderedDict - Stedy
4个回答

3

根据您需要的性能,您可以在每次添加后进行重新排序。类似以下代码(未经测试):

def add(item, aList):
    aList.append(item)
    return sorted(aList, key=lambda entry:"{}{}".format(entry['last_name'], entry['first_name'])

虽然不是很高效,但如果你有灵活性,它就很简单。


2
如果列表是同质的,即所有条目都是一对名称,您可以使用元组而不是字典,因为在这种情况下键没有太多价值。如果您将元组保留在姓氏,名字顺序中,则可以使用bisect:
In [1]: entries = [("fry", "philip"), ("zoidberg", "john")]

In [2]: entries.sort()

In [3]: entries
Out[3]: [('fry', 'philip'), ('zoidberg', 'john')]

In [4]: import bisect

In [5]: bisect.insort(entries, ("turanga", "leela"))

In [6]: entries
Out[6]: [('fry', 'philip'), ('turanga', 'leela'), ('zoidberg', 'john')]

1
你的想法是正确的,bisect 模块可以满足你的需求,并且非常高效。由于它没有 key 函数,因此你需要在调用它之前自己构建一个关键字列表。然后它将返回正确的插入点,供你在列表中使用:
import bisect

entries = [
    {"first_name": "philip", "last_name": "fry"},
    {"first_name": "john", "last_name": "zoidberg"}]

new_entry = {'first_name': 'anne', 'last_name': 'bedford'}

keys = [(d['last_name'], d['first_name']) for d in entries]
entries.insert(bisect.bisect_left(keys, (new_entry['last_name'], new_entry['first_name'])), new_entry)
print entries

这将给您以下输出:


[{'first_name': 'anne', 'last_name': 'bedford'}, {'first_name': 'philip', 'last_name': 'fry'}, {'first_name': 'john', 'last_name': 'zoidberg'}]

1
一种不太简单但更有效的方法是使用 sortedcontainers 模块(它使用了您猜测的 bisect)。
您必须扩展 dict 以使其可排序。
class Person(dict):
    def __lt__(self, other):
        return '{}{}'.format(self['last_name'], self['first_name']) <
               '{}{}'.format(other['last_name'], other['first_name'])

然后将Person对象添加到一个已排序的列表中:
from sortedcontainers import SortedList
sorted_list = SortedList()
p = Person()
p['first_name'] = 'philip'
p['last_name']  = 'fry'
sorted_list.append(p)

你实际上可以只使用 sortedcontainers.SortedListWithKey 并创建键函数:lambda value: (value['last_name'], value['first_name']) - GrantJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接