【问题标题】:Is it possible to assign the same value to multiple keys in a dict object at once?是否可以一次将相同的值分配给 dict 对象中的多个键?
【发布时间】:2011-02-27 18:38:40
【问题描述】:

在 Python 中,我需要一个如下所示的字典对象:

{'a': 10, 'b': 20, 'c': 10, 'd': 10, 'e': 20}

通过像这样结合dict.update()dict.fromkeys() 函数,我已经能够成功地做到这一点:

myDict = {}
myDict.update(dict.fromkeys(['a', 'c', 'd'], 10))
myDict.update(dict.fromkeys(['b', 'e'], 20))

但是,由于代码是为可能需要偶尔添加键/值的新手用户编写的,所以我更喜欢简单的准系统(类 Perl)语法,例如:

myDict = {}
myDict['a', 'c', 'd'] = 10
myDict['b', 'e'] = 20

然而,这给了我:

myDict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}

有没有办法可以进一步简化我的第一个示例(使用 dict.update()dict.fromkeys()),并获得我正在寻找的 dict 对象?

或者,或者,如果我有一个带有元组的字典,就像我的第二个示例一样,是否有一种简单的方法可以让我进行查找,例如 myDict['c']myDict.get('c') 并获得值 10?

【问题讨论】:

    标签: python syntax dictionary


    【解决方案1】:

    虽然@SilentGhost 的答案适用于单一长度的键,但对于那些寻找“键的多字符长度”解决方案的人来说,它无法正常工作,所以我想到了以下解决方案 [ ...]

    假设我们有上面的dict 和我们正在寻找的密钥:

    my_dict = {
        'key1':'KEY_1',
        ('tk1', 'tk2','tk3'):'TK_1_2_3',
        'key2':'KEY_2'
    }
    
    my_keys = ['key2','ke', 'tk2','k','key','exception'] # key's I'm looking for
    

    下面的示例和解决方案

    for key in my_keys:
        print(next((v for k, v in my_dict.items() if (key == k) or (isinstance(k,tuple) and key in k)),None))
    

    正确LY输出:

    KEY_2
    None
    TK_1_2_3
    None
    None
    None
    

    虽然有(稍微修改的解决方案[所以它不会抛出StopIteration异常])@SilentGhost的回答

    for key in my_keys:
        print(next((v for k, v in my_dict.items() if key in k),None)) # added ((...),None)
    

    如果不是StopIteration exception,结果是错误because [...]2

    KEY_2
    KEY_1
    TK_1_2_3
    KEY_1
    KEY_1
    None
    

    虽然我个人不会从速度效率的角度真正推荐它(至少不是针对所有用例),但它确实是解决这个问题的一种方法,所以我决定发布它。

    【讨论】:

      【解决方案2】:

      字典联合(3.9+)

      现在with Python 3.9,你可以这样做了:

      myDict = dict.fromkeys(['a', 'c', 'd'], 10) | dict.fromkeys(['b', 'e'], 20)
      

      虽然就个人而言,我不确定我是否会使用它,因为它很难阅读。

      听写理解

      myDict = {
          k: v
          for keys, v in [(['a', 'c', 'd'], 10), (['b', 'e'], 20)]
          for k in keys
          }
      

      这也很难阅读,但为了完整起见,我提一下。

      reference

      【讨论】:

        【解决方案3】:

        与@SilentGhost 类似,但我更喜欢声明式语法 (with Python 3.5+):

        myDict = {
          **dict.fromkeys(['a', 'c', 'd'], 10), 
          **dict.fromkeys(['b', 'e'], 20)
        }
        

        【讨论】:

        • 元组方法不适用于 myDict.get('c'),这就是问题所在。此方法确实按预期工作,无需添加代码来访问或定义字典。这应该是选中的答案。
        • 这是最干净的方式
        【解决方案4】:

        想到了一种方法。 还是有内容相同的限制。

        一个键的值不能改变另一个。

        key_map = {
            'KEY_UP': move_up,
            'w': 'KEY_UP',
        }
          
        for key in key_map:
            # loop over the dict
            
            if key_map[key] in key_map:
                # one key is the value of the other
                
                target_key = key_map[key]
                key_map[key] = key_map[target_key]
                # overwrite key white the contents of the other
        

        【讨论】:

        • 这和问题有什么关系?
        【解决方案5】:

        我想说你所拥有的是非常简单,你可以稍微改进一下:

        my_dict = dict.fromkeys(['a', 'c', 'd'], 10)
        my_dict.update(dict.fromkeys(['b', 'e'], 20))
        

        如果你的键是元组,你可以这样做:

        >>> my_dict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}
        >>> next(v for k, v in my_dict.items() if 'c' in k)      # use .iteritems() python-2.x
        10
        

        当然,这将返回第一个遇到的值,包含给定元素的键。

        【讨论】:

        • OP说代码是为新手写的,这对于新手来说比较难理解。
        • @teleinat:所以写一个他们可以使用的函数。您是否因为我的代码不够愚蠢而严重贬低我?我的代码使用内置方法和函数。这怎么不是基础?为不学习的新手写代码有什么意义?
        • OP 显然知道如何用 Python 编程。我将他的问题解释为是否有针对他的用例的更简单的内置解决方案,而不是是否可以编写这样的函数或用复杂的代码实现他想要的。因此,据我了解,SilentGhost 的回答没有回答这个问题,所以我投了反对票。我最初的评论没有描述我投反对票的原因。
        • @SilentGhost:IMO 的 OP 知道如何编程,并且可以自己想出类似的东西;他在问是否有一个现有的、简单的机制来解决这个问题,例如。内置或在标准库中。
        • @SilentGhost 我不同意。我已经用 Python 编程九年了,但我仍然偶尔会了解标准库中的新功能。知道使用一种语言和了解它的整个标准库是非常不同的事情。但是,我认为我们中的任何一个都不会被说服,所以让我们同意不同意。
        【解决方案6】:

        方法:

        def multi_key_dict_get(d, k):
            for keys, v in d.items():
                if k in keys:
                    return v
            return None
        

        用法:

        my_dict = {
           ('a', 'b', 'c'): 10,
           ('p', 'q', 'r'): 50
        }
        
        value = multi_key_dict_get(my_dict, 'a')
        

        【讨论】:

          【解决方案7】:

          为什么不从 dict 继承?

          class LazyDict(dict):
              def keylist(self, keys, value):
                  for key in keys:
                      self[key] = value
          
          >>> d = LazyDict()
          >>> d.keylist(('a', 'b', 'c'), 10)
          >>> d
          {'a': 10, 'c': 10, 'b': 10}
          

          但我更喜欢循环解决方案

          【讨论】:

          • 这和dict.fromkeys()完全一样。唯一的区别是它的value 默认为None
          【解决方案8】:

          您的第一个示例可以使用循环来简化:

          myDict = {}
          for key in ['a', 'c', 'd']:
              myDict[key] = 10
          for key in ['b', 'e']:
              myDict[key] = 20
          

          没有专门的语法或诡计,我想不出任何更容易理解的东西。

          关于您的第二个问题,没有像第二个示例中那样简单有效的查找方法。我只能想到遍历键(元组)并检查键是否在其中任何一个中,这不是您要寻找的。坚持使用带有您想要的键的简单字典。

          一般来说,如果您的目标是编写新手可以理解的代码,请坚持使用 if 条件和 for/while 循环等基础知识。

          【讨论】:

            猜你喜欢
            • 2015-02-09
            • 2014-07-06
            • 2017-05-24
            • 1970-01-01
            • 2022-01-24
            • 2022-01-20
            • 2020-11-10
            相关资源
            最近更新 更多