Python字典中的反向键(由列表组成)和值
我一直试图从这里的其他帖子中找出这个问题,但是没有 我有一本Python字典Python字典中的反向键(由列表组成)和值,python,dictionary,list-comprehension,state-machine,Python,Dictionary,List Comprehension,State Machine,我一直试图从这里的其他帖子中找出这个问题,但是没有 我有一本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
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],
}
(这描述了有限状态机的边缘,我需要向后运行它:它必须像以前一样接受反向输入)
例如,在旧字典中,第一个键是一个列表(1,'a'):[2]
,现在,这个键应该变成(2,'a'),[1]
。。。或者(4,'y'):[5]
变成(5,'y'):[4]
等等-我希望我的意思可以理解
我一直试图用列表的理解来解决这个问题,但还没有成功
更新:我尝试了他的建议,但不知何故,我无法让代码正常工作。我将其插入到函数中,如下所示:
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知之甚少,因此如果我犯了一个太愚蠢的错误,请原谅我…这足够复杂,我不必费心理解列表。另外,我假设您不希望值列表有任何严格的顺序
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)
这适用于你的数据,只是为了好玩,把它当作一个丑陋的黑客 最好用更多的代码行来编写,这样更容易理解,但有时我还是忍不住要编写这个装置 希望能有帮助
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.
它用来使测试它是否做了你想做的事情变得更容易。我认为你对
口述的目的理解有问题。dict
数据结构不应被认为是以任何特定方式排序的,因为它使用哈希表来访问元素。您应该阅读,并且中关于实现细节的说明。items()
也很重要。事实证明,实现可能会给您看起来期望的顺序,但您不应该指望它
如果订单对您很重要,那么您应该至少在代码中订单重要的部分使用列表
。使用dict
上的.items()
方法获取(键、值)
对的列表,然后可以使用列表上的常用排序方法对它们进行任意排序 我建议使用items()
而不是iteritems()
,因为它适用于Python2.x和3.x,并且OP的问题似乎不会因为获得一个完全格式的列表而受到不利影响(在Python2.x的情况下)。一般来说,我认为我们应该推荐Python3语法,只要它在Python2中也可以使用,并且没有指定版本。@JohnY,我认为这是一个非常好的观点。但另一方面,我也有不少评论员抱怨我过去没有使用iteritems
。我习惯于更多地使用iteritems
来表示我意识到了手头的问题,我认为我的读者也是。然后,如果出现这种情况,我可以随时补充必要的注意事项。另外——如果在Python 2中浪费地使用项,您不会得到任何警告,但是在Python 3中,如果您尝试使用iteritems
,您会立即意识到有问题。所以我现在倾向于使用iteritems
。嗨,森德尔和约翰尼,谢谢。。。老实说,这两个我都不知道,但无论如何,我是否必须导入一些库才能工作?我收到一个错误“dict”对象没有属性“iteritems”我做错了什么?@Jens按照johny的建议使用items()
而不是iteritems()
@senderle:我过去在展示非惰性版本时也会遇到静态问题。你不会赢的嗨,F.C.谢谢你。不知何故,我无法使它工作。。。如果代码如下所示:old_dict1={(1,'a'):[2],(2,'b'):[3,4],(3,'x'):[5],(5,'b'):[3,4],(5,'c'):[6],}def reverse_dict(old_dict):new_dict={}add to_dict=new_dict.setdefault,您可以使用[defaultdict][1]映射(lambda kv:将_添加到_dict(kv[0],])。附加(kv[1]),如果kv[0]不在dict中,则获取[],并将其相加([[((x,k[1]),k[0]),对于x in v,对于k,v在旧_dict.items(),[]))#sum将以此开始添加return new_dictHi,我只知道很少的Python,事实上……但是字典是一个键值对,我基本上想让键成为值,值成为键(其中键是元组,值是一个或多个项的列表),根本不关心钥匙的顺序。很抱歉我的误解。当我读到你想要的东西时,我一定是在读的时候很匆忙。我处理了你在你的问题中发布的答案中的信息。如果你认为它不再相关,请随时删除它。@senderle谢谢…我仍然不知道他的一个工作,仍然只得到一个空字典返回。但无论如何,你的另一个职位已经为我工作得很好了!