Python字典中的反转键(由列表组成)和值

2024-04-27 23:11:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直试图从其他帖子中找到答案,但没能

我有一本Python字典

old_dict = { (1,'a') : [2],
          (2,'b') : [3,4],
          (3,'x') : [5],
          (4,'y') : [5],
          (5,'b') : [3,4], 
          (5,'c') : [6],
          }

我需要把这个颠倒过来,这样我就可以:

^{pr2}$

(这描述了一个有限状态机的边缘,我需要向后运行它:它必须像以前一样接受反向输入)

例如,在旧的dict中,第一个键是一个list (1, 'a') : [2],现在,这个键应该变成(2, 'a'), [1]。。。或者(4,'y') : [5]变成{}等等。-我希望我的意思是可以理解的。在

我一直试图用列表理解来解决这个问题,但是还没有成功。在

更新:我尝试了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知之甚少,所以如果我犯了一个愚蠢的错误,请原谅我…)


Tags: to答案inaddnewfor字典old
3条回答

这太复杂了,我不必费心去理解列表。另外,我假设您不希望值列表按任何严格的顺序排列。在

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

^{pr2}$

对于那些有兴趣尽可能简洁的人,我想到这个更压缩的版本也是一个选择。从可读性的角度来看,我不确定我对此有何看法,因此我更改了变量名以使其更清晰:

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)

我认为你对dict目的的理解有问题。dict数据结构不应该被认为是以任何特定的方式排序的,因为它使用哈希表来访问元素。您应该阅读docs,并且关于.items()here中实现细节的说明也很重要。事实证明,实现可能会给您提供您似乎期望的顺序,但您不应该指望它。在

如果顺序对您很重要,那么您至少应该在代码中顺序重要的部分使用list。对您的.items()方法使用dict来获得(key,value)对的列表,然后您可以使用列表上常用的排序方法对它们进行任何排序。在

把你那丑陋的数据拿来吧。在

最好用更多的代码行来完成,这样更容易理解,但有时我无法抗拒编写这个小发明的诱惑。在

希望有帮助。在

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并按如下方式运行:

^{pr2}$

它使用^{}来更容易地测试它是否做了您想要的。在

相关问题 更多 >