在 defaultdict 中获取每个列表的第 n 个元素

Getting the n element of each list in a defaultdict

我有 defaultdict(list) 个:

d_int = defaultdict(type, {0: [1,2,3,4,5], 1: [6,7,8,9,10], 2: [11,12,13,14,15]})

有没有一种 pythonic 方法可以将每个列表中的每个 n 元素保存到一个新数组中,所以我有这样的东西?:

a = [1,6,11]
b = [2,7,12]
c = [3,8,13]
d = [4,9,14]
e = [5,10,15]

下面的代码将计算一个数组nth_el,例如nth_el[i]包含所有i-th个元素:

d_int = defaultdict(type, {0: [1,2,3,4,5], 1: [6,7,8,9,10], 2: [11,12,13,14,15]})

nth_el = [[d_int[k][i] for k in range(3)] for i in range(5)]

nth_el 的值:

[[1, 6, 11], [2, 7, 12], [3, 8, 13], [4, 9, 14], [5, 10, 15]]

字典不被认为是有序的。但是,获得所需输出的一种方法是构造 collections.defaultdict 对象的 collections.OrderedDict,然后应用一些 zip 魔法:

from collections import OrderedDict, defaultdict

d_int = OrderedDict(sorted(defaultdict(list, {0: [1,2,3,4,5],
                           1: [6,7,8,9,10], 2: [11,12,13,14,15]}).items()))

dict(enumerate(zip(*d_int.values())))

# {0: (1, 6, 11), 1: (2, 7, 12), 2: (3, 8, 13), 3: (4, 9, 14), 4: (5, 10, 15)}

此方法的好处是您不必提取字典及其组成列表的长度。此外,enumeratezip 都是高效的惰性函数。

示例输出几乎肯定是不切实际的;如果我们有同类数据,请将其放入列表中。这是一个粗略的例子:

>>> d_int = defaultdict(type, {0: [1,2,3,4,5], 1: [6,7,8,9,10], 2: [11,12,13,14,15]})
>>> list(zip(*(v for k,v in sorted(d_int.items()))))
[(1, 6, 11), (2, 7, 12), (3, 8, 13), (4, 9, 14), (5, 10, 15)]

步骤如下:items从字典中提取key,value对。 sorted 然后按键对它们进行排序,v for k,v in 生成器表达式丢弃键,* 将值作为单独的参数分发给 zip 并转置它们。最后,list 从 zip 对象(可迭代)构建一个列表。