在python 3.X中使用不同长度的列表反转字典

时间:2018-11-18 18:27:40

标签: python dictionary

这是我的代码(受其他线程的代码启发):

def inverter(a):
    b = {}
    for k,v in a.items():
        for i in v:
            b.setdefault(i,[]).append(k)
    return b

x={'orange':['apple','peach'], 'cherry':'grape'}
print(inverter(x))

问题在于它会返回以下输出:

{'apple': ['orange'], 'peach': ['orange'], 'g': ['cherry'], 'r': ['cherry'], 'a': ['cherry'], 'p': ['cherry'], 'e': ['cherry']}

它似乎遍历每个最后一个字母,而不是遍历一次。 我该如何解决? 谢谢

5 个答案:

答案 0 :(得分:1)

这解决了问题。如果有更优雅的解决方案,将不胜感激:

def inverter(a):
b = {}
for k,v in a.items():
    if type(v) is list:
        for i in v:
            b.setdefault(i,[]).append(k)
    else:
        b.setdefault(v,[]).append(k)

return b

x={'orange':['apple','peach'], 'cherry':'grape'}
print(inverter(x))

答案 1 :(得分:1)

宫城先生的评论是您遇到问题的原因。通过遍历v(其中v='grape'),您将得到每个单独的字母,因为您正在遍历字符串。要解决此问题,您可以检查实例类型:

def inverter(a):

    b = {}
    for k,v in a.items():
        if isinstance(v, list):
            for i in v:
                b.setdefault(i,[]).append(k)
        else:
            b.setdefault(v, []).append(k)
    return b
x={'orange':['apple','peach'], 'cherry':'grape'}
print(inverter(x))

答案 2 :(得分:1)

问题在于,有时您的值是应迭代的列表,有时您的值是应保持在一起但可迭代的字符串。

请考虑以下内容:

def pairs_from_dict(d): 
    for k, v in d.items():
        if isinstance(v, str):
            yield (v, k)
        else:
            yield from ((k_i, k) for k_i in v)

上面的生成器假定dict值要么是字符串,要么应该被迭代,但是您可以对心脏的内容添加其他检查。

还假定您要从中生成键的所有值都是唯一的,例如原始字典中没有{'cherry': 'grape', 'banana':'grape'},因为字典键必须唯一。

它是这样的:

>>> d = {'orange':['apple','peach'], 'cherry':'grape'}
>>> dict(pairs_from_dict(d))
{'apple': 'orange', 'grape': 'cherry', 'peach': 'orange'}

答案 3 :(得分:0)

问题在于您的某些词典值是列表,其他是字符串。字符串是可迭代的,就像列表一样,因此您会看到字母用作键。

您可以将三元语句用于条件逻辑。另外,更有效的方法是使用collections.defaultdict

from collections import defaultdict

def inverter(a):
    b = defaultdict(list)
    for k,v in a.items():
        for i in v if isinstance(v, list) else [v]:
            b[i].append(k)
    return b

x = {'orange':['apple','peach'], 'cherry':'grape'}

print(inverter(x))

defaultdict(<class 'list'>,
            {'apple': ['orange'], 'peach': ['orange'], 'grape': ['cherry']})

答案 4 :(得分:0)

正如其他人已经写过的那样,问题在于有时您的值是列表,有时您的值是字符串,它们本身具有可迭代性。 一种可能的解决方案:

def inverter(a):
    b = []
    for k,v in a.items():
        if isinstance(v,list):
            b.extend([[x,k] for x in v])
        else: 
            b.append([v,k])
    return dict(b)

x={'orange':['apple','peach'], 'cherry':'grape'}
print(inverter(x))

退出:

{'apple': 'orange', 'peach': 'orange', 'grape': 'cherry'}