[英]Python - append to list of dicts while keeping order
我有一个python列表,其中包含个人信息的序列,如下所示:
entries = [
{
"first_name": "philip",
"last_name": "fry"
},
{
"first_name": "john",
"last_name": "zoidberg"
}
]
我想在此列表中添加条目,例如维持升序(姓氏,名字)顺序的方式。 bisect模块看起来很有前景,但似乎并不支持这一点。
任何帮助表示赞赏!
根据您需要的性能,您可以在每次添加后求助。 像(未经测试的代码):
def add(item, aList):
aList.append(item)
return sorted(aList, key=lambda entry:"{}{}".format(entry['last_name'], entry['first_name'])
它效率不高,但如果你有灵活性,那很简单。
如果列表是同类的,即所有条目都是一对名称,则可以使用元组而不是dicts,因为在这种情况下键不会增加太多值。
如果您将元组保留为姓氏,则可以使用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')]
您认为bisect
模块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'}]
一种不太简单但更有效的方法是使用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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.