【问题标题】:Is there a way to preserve duplicate keys in python dictionary [duplicate]有没有办法在python字典中保留重复键[重复]
【发布时间】:2012-06-21 15:20:12
【问题描述】:

有没有办法在字典中存储重复的键?

我有一个特定的要求来形成一对请求和响应。

从一个特定节点到另一个特定节点的请求形成相同的密钥。我需要存储这两个。

但如果我尝试将它们添加到字典中,第一个将被第二个替换。有什么办法吗?

【问题讨论】:

  • 根据定义不允许 字典是否允许重复键?
  • 一看到“节点”这个词,我就想到了“图”。您能否进一步评论您的最终目标,而不是您认为可能遇到的实施问题

标签: python


【解决方案1】:

虽然我不能 100% 确定,但我很确定答案是否定的。这种违反了python中字典的目的。您如何将值更改为列表而不是

{Key:value}

你有

{Key:[Value1,value2]}

【讨论】:

    【解决方案2】:

    使用列表存储相等键的所有值:

    {a:b, a:c}  # foolish, won't work
    {a: [ b, c ]}  # works like a charm!
    

    您可能还想使用

    from collections import defaultdict
    d = defaultdict(list)
    d[a].append(b)
    

    以一种简单的方式填写您的字典。

    【讨论】:

    • 好的,我明白了...我可以使用 count 作为字典的键,对于我添加的每个列表作为值,对于下一个条目,我可以增加计数。
    【解决方案3】:

    没有办法做到这一点,不。字典依赖于唯一的键 - 否则,当您请求或设置键时,会返回或覆盖什么值?

    但是,您可以做的是将列表存储为字典的值,然后将您的值添加到该列表中,而不是替换现有值。

    您可能希望使用collections.defaultdict 来执行此操作,以避免每次引入新密钥时手动制作列表。

    【讨论】:

    • 那本字典的键是什么?
    • 好的,我明白了...我可以使用 count 作为字典的键,对于我添加的每个列表作为值,对于下一个条目,我可以增加计数。
    • @rockluke 你在那里描述的是一个列表,而不是字典。如果您的键是索引,那么列表更合适。
    • @Feiteira 您描述的是一种不同的情况——根据定义,这些键不是重复的(它们彼此不相等)。它使字典基本上无用,因为您必须拥有确切的键对象才能访问该值。到那时,为什么不把值放在键对象中并完全放弃字典呢?你当然可以通过迭代来访问它们,但是为什么不直接使用元组列表呢?
    【解决方案4】:

    defaultdict 的替代方法可能是

    d = {}
    d.setdefault(newkey, []).append(newvalue)
    

    这也是一样的:将newvalue 附加到一个列表中,该列表要么已经在给定newkey 的字典中,否则将被放在那里。

    【讨论】:

      【解决方案5】:

      更优雅的解决方案:

      def add_to_dict(towhat, key, value):
          info = towhat.get(key, [])
          info.append(value)
          towhat[key] = info
      
      alternate = {}
      
      add_to_dict(alternate,"Andrew","Cambridge")
      add_to_dict(alternate,"Barbara","Bloomsbury")
      add_to_dict(alternate,"Andrew","Corsica")
      
      print alternate
      

      【讨论】:

        【解决方案6】:

        假设您想继续使用字典,我可以想到两个简单的选项。

        1. 您可以将键映射到项目列表。来自collections 模块的defaultdict 让这一切变得简单。

          >>> import collections
          >>> data = collections.defaultdict(list)
          >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')):
          ...     data[k].append(v)
          ... 
          >>> data
          defaultdict(<type 'list'>, {'a': ['b', 'c'], 'b': ['c']})
          
        2. 您可以使用其他数据来消除键的歧义。这可以是时间戳、唯一 ID 号或其他内容。这具有保留键和值之间的一对一关系的优点,以及使查找更复杂的缺点,因为您始终必须指定id。下面的例子展示了它是如何工作的;是否对您有好处取决于问题域:

          >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')):
          ...     i = 0
          ...     while (k, i) in data:
          ...         i += 1
          ...     data[(k, i)] = v
          ... 
          >>> data
          {('a', 1): 'c', ('b', 0): 'c', ('a', 0): 'b'}
          

        【讨论】:

          【解决方案7】:

          我喜欢使用collections.defaultdict 的答案。这就是我可能会走的路。

          但这假设一个 dict 或类似 dict 的结构和一对多映射是正确的解决方案。重读这个问题,“形成请求和响应对”的要求可能会导致更简单的元组列表(或列表列表)方法。例如:

          pairs = []
          pairs.append( (request, response) )
          

          这可能会创建一个类似的列表:

          [ ('GET /', 200), ('GET /index.html', 200), ('GET /x', 403), ('GET /', 200), ]
          

          它只是结构简单,但取决于你想用它做什么,可能没问题。

          【讨论】:

            【解决方案8】:

            根据定义,字典要求键是唯一标识符。您可以:

            1. 使用不同的数据结构,例如允许重复条目的列表或元组。
            2. 为您的字典键使用唯一标识符,这与数据库可能使用自动递增字段作为其键 ID 的方式非常相似。

            如果您要存储大量请求/响应对,那么最好还是使用数据库。这当然值得考虑。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-05-06
              • 2010-10-18
              • 2022-12-05
              • 2014-09-04
              相关资源
              最近更新 更多