我一直在试图从这里的其他帖子中找出这一点,但做不到。
我有一本Python字典
old_dict = { (1,'a') : [2],
(2,'b') : [3,4],
(3,'x') : [5],
(4,'y') : [5],
(5,'b') : [3,4],
(5,'c') : [6],
}我需要扭转这一局面,这样我就可以:
new_dict = { (6,'c') : [5],
(5,'x') : [3],
(5,'y') : [4],
(4,'b') : [5, 2],
(3,'b') : [5, 2],
(2,'a') : [1],
}(这描述了有限状态机的边缘,我需要向后运行它:它必须像以前一样接受反向输入)
例如,在old_dict中,第一个键是list (1, 'a') : [2],现在,这个键应该变成(2, 'a'), [1] .或者(4,'y') : [5]变成(5,'y') : [4]等等-我希望我的意思是可以理解的。
我一直试图用清单理解来解决这个问题,但还没有成功。
Update:,我尝试了F.C.的建议,但不知怎么我无法让代码工作。我把它插入到一个函数中,如下所示:
old_dict1 = { (1,'a') : [2],
(2,'b') : [3,4],
(3,'x') : [5],
(4,'y') : [5],
(5,'b') : [3,4],
(5,'c') : [6],
}
def reverse_dict(old_dict):
new_dict = {}
add_to_dict = new_dict.setdefault
map(lambda kv: add_to_dict(kv[0], []).append(kv[1]),
sum([[((x, k[1]), k[0]) for x in v] for k, v in old_dict.items()],
[])) # sum will take this to start adding
return new_dict
new_dict1 = reverse_dict(old_dict1)
print(new_dict1)但我只得到了一个空字典{}
我做错什么了吗?(我对Python知之甚少,所以如果我犯了一个太愚蠢的错误,请原谅我……)
发布于 2012-06-01 22:11:07
这是足够复杂的,我不会费心于清单的理解。另外,我假设您并不是在寻找严格顺序的值列表。
new_dict = {}
for k, vals in old_dict.items():
k_num, k_char = k
for num in vals:
new_dict.setdefault((num, k_char), []).append(k_num)或者使用defaultdict
new_dict = collections.defaultdict(list)
for k, vals in old_dict.items():
k_num, k_char = k
for num in vals:
new_dict[(num, k_char)].append(k_num)对于那些对尽可能简洁感兴趣的人来说,我觉得这个更压缩的版本也是一种选择。从可读性的角度来看,我不太清楚自己对此的看法,因此我更改了变量名,以获得更清晰的信息:
new_dict = collections.defaultdict(list)
for (num_in, char_in), nums_out in old_dict.items():
for num_out in nums_out:
new_dict[(num_out, char_in)].append(num_in)发布于 2012-06-01 22:51:38
这适用于您的数据,把它当作一个丑陋的黑客,仅仅是为了好玩的。
最好在更多的代码行中这样做,这样可以更容易理解,但有时我无法抗拒编写这些工具的诱惑。
希望能帮上忙。
def reverse_dict(old_dict):
"""
>>> sorted(reverse_dict({(1,'a'): [2],
... (2,'b'): [3,4],
... (3,'x'): [5],
... (4,'y'): [5],
... (5,'b'): [3,4],
... (5,'c'): [6],
... }).items())
[((2, 'a'), [1]), ((3, 'b'), [2, 5]), ((4, 'b'), [2, 5]), ((5, 'x'), [3]), ((5, 'y'), [4]), ((6, 'c'), [5])]
"""
new_dict = {}
add_to_dict = new_dict.setdefault # you could use a [defaultdict][1] instead
map(lambda kv: add_to_dict(kv[0], []).append(kv[1]), # if kv[0] not in dict get [] and add to it
sum([[((x, k[1]), k[0]) for x in v] for k, v in old_dict.items()],
[])) # sum will take this to start adding
return new_dict要测试代码,只需将其复制到文件so.py并按如下方式运行:
$ python -m doctest so.py -v
Trying:
sorted(reverse_dict({(1,'a'): [2],
(2,'b'): [3,4],
(3,'x'): [5],
(4,'y'): [5],
(5,'b'): [3,4],
(5,'c'): [6],
}).items())
Expecting:
[((2, 'a'), [1]), ((3, 'b'), [2, 5]), ((4, 'b'), [2, 5]), ((5, 'x'), [3]), ((5, 'y'), [4]), ((6, 'c'), [5])]
ok
1 items had no tests:
so
1 items passed all tests:
1 tests in so.reverse_dict
1 tests in 2 items.
1 passed and 0 failed.
Test passed.它使用doctest可以更容易地测试它是否做了您想做的事情。
发布于 2012-06-02 05:27:15
我认为在您理解dict的目的方面存在一个问题。不应将dict数据结构视为以任何特定方式排序,因为它使用哈希表访问元素。您应该阅读文档,关于.items() 这里中的实现细节的说明也很重要。事实证明,实现可能会给您带来您期待的顺序,但您不应该指望它。
如果订单对您很重要,那么您至少应该在您的代码的重要部分使用list。在您的.items()上使用dict方法获取(key,value)对的列表,然后可以使用列表上常用的排序方法对它们进行排序。
https://stackoverflow.com/questions/10857907
复制相似问题