我有一份清单list1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']]
从列表1中制作OrderedDict的最快方法是什么?
{colour:['red','blue'],shape:['rect','square']}
到目前为止,我已经能够通过list1进行映射并提取每个内部列表的索引0中的唯一元素,并将其作为list2返回。
我可以通过list1和list2进行映射,如果找到了maching元素,那么从list1的每个内部列表中获取索引1处的元素,但我不确定它是否是正确的方法/快速方法。
有什么帮助吗?
答案 0 :(得分:0)
两种方法,取决于您的输入:
选项1:如果在您的示例中,所有匹配的键都是连续的(因此您始终可以看到所有colours
),则可以使用itertools.groupby
对它们进行分组:
from collections import OrderedDict
from itertools import groupby
from operator import itemgetter
list1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']]
dict1 = OrderedDict((k, [v for _, v in grp]) for k, grp in groupby(list1, itemgetter(0)))
这至少在理论上是最快的方法,因为它每次在dict
中写入每个键而不会在每次看到一个键时重复查找它,但它依赖于按键排序的输入
选项2:使用__missing__
特殊方法在OrderedDict
上查找缺失的密钥时使defaultdict(list)
具有相同的行为(遗憾的是,这两种类型不兼容,所以你不能创建一个继承自两者的类并在一天内调用它,然后编写一个显式循环来填充它:
from collections import OrderedDict
class OrderedMultidict(OrderedDict):
__slots__ = () # Avoid overhead of per-instance __dict__
def __missing__(self, key):
# Missing keys are seamlessly initialized to an empty list
self[key] = retval = []
return retval
然后用它来积累结果:
dict1 = OrderedMultidict()
for k, v in list1:
dict1[k].append(v)
此方法删除了选项1的排序依赖性,以换取添加每个键的重复查找(尽管只有第一个查找调用__missing__
中的Python级别代码;之后,如果OrderedDict
为C与现代Python 3代码一样,查找也将保持C级别)。也就是说,虽然重复查找在理论上比仅写一次密钥差一些,但实际上我怀疑这个解决方案在现代CPython上会更快(其中OrderedDict
是C内置的);在Python 2和更早的Python 3上,它是用Python实现的(虽然groupby
总是C级),groupby
更有可能获胜,但当两种类型都是C加速时,groupby
实际上有一些额外的开销可能会让它失败。