gpt4 book ai didi

python - 字典值排序

转载 作者:行者123 更新时间:2023-11-28 21:25:09 26 4
gpt4 key购买 nike

我有一个以元组作为键(包含一个字符串和一个 int)并以 float 作为值的字典。一个例子:

first = {}
first['monkey', 1] = 130.0
first['dog', 2] = 123.0-
first['cat', 3] = 130.0
first['cat', 4] = 130.0
first['mouse', 6] = 100.0

现在,我需要制作一个新字典,其中包含原始字典键的第二个元素这是关键。如果键被排序,新字典的值应该是它所在的位置。除此之外,还有两个异常(exception):

  1. 如果两个字典的值相等,但键中的字符串不同,则键中 int 值最小的字典应该放在更高的位置。

  2. 如果两个字典的值相等,但键中的整数不同,则它们在新字典中的位置应该相等,并且都得到相同的值。

所以,新字典应该是这样的:

second[1] = 3
second[2] = 2
second[3] = 4
second[4] = 4
second[6] = 1

我知道要求别人解决我的问题而不提供我的代码是无知的。但我根本不知道如何解决这个问题。如果你能向我解释你将如何解决这个问题,或者甚至给我一个算法的伪代码,我会很高兴。

最佳答案

import itertools as IT

first = {
('monkey',1): 130.0,
('dog',2): 123.0,
('cat', 3): 130.0,
('cat', 4): 130.0,
('mouse', 6): 100.0
}

counter = 0
ordered = sorted(first, key = lambda k: (first[k], k[1], k[0]))

second = {}
for key, group in IT.groupby(ordered, first.__getitem__):
# group = list(group)
# print(key, group)
# (100.0, [('mouse', 6)])
# (123.0, [('dog', 2)])
# (130.0, [('monkey', 1), ('cat', 3), ('cat', 4)])
previous = None
for name, num in group:
if name != previous:
counter += 1
second[num] = counter
previous = name

print(second)

产量

{1: 3, 2: 2, 3: 4, 4: 4, 6: 1}

解释:

第一步是根据关联的值对 first(name, num) 键进行排序。但是,如果出现平局,则使用 num。如果仍然平局,则使用 name 打破平局。

In [96]: ordered = sorted(first, key = lambda k: (first[k], k[1], k[0]))

In [97]: ordered
Out[97]: [('mouse', 6), ('dog', 2), ('monkey', 1), ('cat', 3), ('cat', 4)]

接下来,我们需要对 ordered 中的项目进行分组,因为当值 first[k] 相同时有特殊规则。可以使用 itertools.groupby 实现分组:

In [99]: for key, group in IT.groupby(ordered, first.__getitem__):
....: print(key, list(group))
....:
....:
(100.0, [('mouse', 6)])
(123.0, [('dog', 2)])
(130.0, [('monkey', 1), ('cat', 3), ('cat', 4)])

itertools.groupby 正在根据键 first.__getitem__(item) 的值将 ordered 中的项目收集成束。例如,

In [100]: first.__getitem__(('monkey', 1))
Out[100]: 130.0

In [101]: first.__getitem__(('cat', 3))
Out[101]: 130.0

first.__getitem__(item) 只是一种编写first[item] 的奇特方式。我之所以使用 first.__getitem__ 是因为 itertools.groupby 需要一个函数作为它的第二个参数,而 first.__getitem__ 是那个函数符合要求。


最后,我们遍历每个组。基本上,我们想这样做:

for name, num in group:
counter += 1
second[num] = counter

除了,当名称相等时,我们不想推进计数器。所以要检查名称是否相等,它有助于存储以前的名称:

previous = None
for name, num in group:
if name != previous:
counter += 1
...
previous = name

警告:请注意,rkd91 的代码和我的代码对

产生了不同的答案
first = {
('monkey',1): 130.0,
('dog',2): 123.0,
('cat', 3): 129.0,
('cat', 4): 130.0,
('mouse', 6): 100.0
}

可能是由于对规范的不同解释。我会留给您来决定哪个会产生所需的输出。

@rdk91 的代码产出

{1: 4, 2: 2, 3: 5, 4: 3, 6: 1}

我的代码产出

{1: 4, 2: 2, 3: 3, 4: 5, 6: 1}

关于python - 字典值排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14863350/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com