【问题标题】:Swapping keys and values with nested value items用嵌套的值项交换键和值
【发布时间】:2012-02-08 00:45:12
【问题描述】:

我有一个标准名称列表

standard = ["Richard","Robert","Nicolas"]

还有一个别名字典(在这种情况下是昵称)

aliases = {standard[0]:["Richard","Rick","Dick","Rich"],
           standard[1]:["Robert","Roberto","Bob"],
           standard[2]:["Nicolas","Nick","Nic"]}

我想制作一个新字典,我可以将任何别名作为键放入其中,它将返回标准名称 AKA 交换键和值

到目前为止,我唯一的猜测是这个

t = {}
aliases = [t.update(zip(v,[k]*len(v))) for k,v in aliases.items()]
aliases = t

有没有更简洁或更易读的方法来做到这一点(id 不喜欢临时字典 t)。

【问题讨论】:

  • 只有在您确实需要列表时才应使用列表推导式。在您的代码中,该列表由 None 值组成,显然没有用。将这样的列表推导式转换为简单的 for 循环可以使代码更具可读性。

标签: python dictionary nested


【解决方案1】:

我认为这将更具可读性:

rev_aliases = {}
for name, nick_list in aliases.iteritems():
    for nick in nick_list:
        rev_aliases[nick] = name

如果你喜欢某种形式的生成器表达式,你可以使用这些:

Python >= 2.7:

rev_aliases = {nick: name 
               for name, nick_list in aliases.viewitems()
               for nick in nick_list}

Python

rev_aliases = dict((nick, name)
                   for name, nick_list in aliases.iteritems()
                   for nick in nick_list)

【讨论】:

  • 我认为循环是最易读的。发电机是我试图炮制的。谢谢你的好答案!
【解决方案2】:
>>> standard = ["Richard","Robert","Nicolas"] 
>>> aliases = {standard[0]:["Richard","Rick","Dick","Rich"], 
           standard[1]:["Robert","Roberto","Bob"] ,
           standard[2]:["Nicolas","Nick","Nic"] }
>>> def name(nickname):
        return [n for n in aliases if nickname in aliases[n]]

>>> name('Bob')
['Robert']
>>> 

列表推导很棒。

【讨论】:

  • 对此只是公平的警告,name() 将遍历所有aliases,这将比在 SvenMarnach 的代码中进行字典访问要慢得多。
  • 是的,但有可能有两个昵称可以解析为同一个名字(“Chris”->“Christopher”、“Christine”;“Willy”->“Bill”、“William” ) 它不会返回所有值。虽然我想修改他的方法来处理这将是微不足道的,所以不管真的
【解决方案3】:

dict((nick, name) for name, nicks in aliases.iteritems() for nick in nicks)

【讨论】:

    【解决方案4】:

    一种滥用 itertools 的有趣方式:

    >>> from itertools import izip, repeat, chain
    >>> dict(chain.from_iterable(
            izip(iter(b), repeat(a, len(b)))
            for a, b in aliases.iteritems()))
    {'Nicolas': 'Nicolas',
     'Richard': 'Richard',
     'Nic': 'Nicolas',
     'Robert': 'Robert',
     'Dick': 'Richard',
     'Roberto': 'Robert',
     'Nick': 'Nicolas',
     'Rick': 'Richard',
     'Rich': 'Richard',
     'Bob': 'Robert'}
    

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      相关资源
      最近更新 更多