我有一个字典,其中元组作为键(包含字符串和int)并浮动为值。一个例子:
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
现在,我需要创建一个新的字典,其原始字典键的第二个元素为 这是关键。如果键被排序,新词典的值应该是它所代表的位置。除此之外,还有两个例外:
因此,新词典应如下所示:
second[1] = 3
second[2] = 2
second[3] = 4
second[4] = 4
second[6] = 1
我知道要求别人解决我的问题而不提供我的代码是无知的。 但我只是不知道如何处理这个问题。如果你能给我一个解释如何解决这个问题,甚至给我一个算法的伪代码,我会很高兴。
答案 0 :(得分:3)
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}
<强>解释强>
第一步是根据相关值对(name, num)
的{{1}}键进行排序。但是,如果是关系,则使用first
。如果仍有平局,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
值相同时存在特殊规则。可以使用itertools.groupby:
first[k]
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
的值将ordered
中的项目收集到一起。例如,
first.__getitem__(item)
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
警告:请注意,rkd91的代码和我的代码会为
生成不同的答案previous = None
for name, num in group:
if name != previous:
counter += 1
...
previous = name
可能是由于对规范的不同解释。我会留给你做决定哪个产生所需的输出。
@ rdk91的代码产量
first = {
('monkey',1): 130.0,
('dog',2): 123.0,
('cat', 3): 129.0,
('cat', 4): 130.0,
('mouse', 6): 100.0
}
我的代码产生
{1: 4, 2: 2, 3: 5, 4: 3, 6: 1}
答案 1 :(得分:2)
1)使用first_list = first.items()
2)创建一个custom comparator function,根据您的标准对列表进行排序。
3)使用first_list.sort(comparator)
4)从排序列表中构建新词典。
答案 2 :(得分:1)
rob@rivertam:~/Programming$ cat sorter.py
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
# Get the keys of first, sorted by the value (ascending order), and then by the integer in the key (descending order) if two keys have the same value
s = sorted(first, key=lambda x: x[0])
s.reverse()
s = sorted(s, key=lambda x: first[x])
# Loop through these, and create a new list where the key is the integer in the old key, and the value is the position in the sorted order.
last_val = None
last = (None, None)
index = 0
new_dict = {}
for item in s:
if not ((first[item] == last_val) and (item[1] != last[1]) and item[0] == last[0]):
# When we have the same value, the same string but a different integer from the last key, consider it to be the same position in the sorted order.
index += 1
new_dict[item[1]] = index
last_val = first[item]
last = item
print new_dict
rob@rivertam:~/Programming$ python sorter.py
{1: 3, 2: 2, 3: 4, 4: 4, 6: 1}