在列表字典的每个索引处查找最小值和最大值

时间:2018-06-13 16:27:35

标签: python

我有一个具有以下结构的字典

{key1: [1,2,3,4,5], key2: [2,0,4,5,6]}

我需要找到值列表的每个索引的最大值和最小值,因此在索引0处,我们比较1 and 2并选择2作为最大值,1作为最大值最小等等。

我的例子的预期输出:

min = [1,0,3,4,5]
max = [2,2,4,5,6]

我不能使用运算符,因为我不允许导入它。我尝试使用以下方法但失败(语法错误)。此外,我不会迭代值集,因为这不是优雅的方式(IMO)。

maxVal = max(myDictionary.items(), key=(lambda k: myDictionary[k]))

给了我

TypeError: unhashable type: 'list'

你能纠正它还是建议任何替代方法。

1 个答案:

答案 0 :(得分:5)

您可以将 zip min max 一起使用

dct = {'key1': [1,2,3,4,5], 'key2': [2,0,4,5,6]}

[min(i) for i in zip(*dct.values())]
[max(i) for i in zip(*dct.values())]

输出:

[1, 0, 3, 4, 5]
[2, 2, 4, 5, 6]

如果你想变得非常花哨,你还可以使用zip的转置技巧两次将其变成单行:

min_list, max_list = map(list, zip(*[(min(i), max(i)) for i in zip(*dct.values())]))

min_list
[1, 0, 3, 4, 5]

max_list
[2, 2, 4, 5, 6]

这种奇特的方法在空列表中表现不佳

例如:

dct = {1: [], 2: []}

会打破这种方法。事实上,几乎所有打破这种方法的方法都涉及在某处使用空列表。

我已经两次提到了 zip 转置技巧,所以这就是为什么这里有必要:

如果您只是使用 list(zip(dct.values())) ,您将获得以下输出:

[([2, 0, 4, 5, 6],), ([1, 2, 3, 4, 5],)]

这不是理想的结果,我们希望对子列表的每个索引处的每个元素进行成对比较。但是,当您使用*运算符时,我们可以利用zip is its own tranpose这一事实。

因此,使用 list(zip(*dct.values())) 为我们提供了我们所需的成对分组进行比较:

[(2, 1), (0, 2), (4, 3), (5, 4), (6, 5)]