代码之家  ›  专栏  ›  技术社区  ›  holmb

比较dict并更新结果列表

  •  1
  • holmb  · 技术社区  · 16 年前

    我有一个dict列表,我想将该列表中的每个dict与结果列表中的dict进行比较,如果不存在,则将其添加到结果列表中,如果存在,则更新与该dict关联的计数器。

    起初,我想使用 Python : List of dict, if exists increment a dict value, if not append a new dict 但是我有一个错误,一个dict不能用作另一个dict的键。

    所以我选择的数据结构是一个列表,其中每个条目都是一个dict和一个int:

    r = [[{'src': '', 'dst': '', 'cmd': ''}, 0]]
    

    原始数据集(应与结果数据集进行比较)是一个dict列表:

    d1 = {'src': '192.168.0.1',
          'dst': '192.168.0.2',
          'cmd': 'cmd1'}
    d2 = {'src': '192.168.0.1',
          'dst': '192.168.0.2',
          'cmd': 'cmd2'}
    d3 = {'src': '192.168.0.2',
          'dst': '192.168.0.1',
          'cmd': 'cmd1'}
    d4 = {'src': '192.168.0.1',
          'dst': '192.168.0.2',
          'cmd': 'cmd1'}
    o = [d1, d2, d3, d4]
    

    结果应该是:

    r = [[{'src': '192.168.0.1', 'dst': '192.168.0.2', 'cmd': 'cmd1'}, 2],
         [{'src': '192.168.0.1', 'dst': '192.168.0.2', 'cmd': 'cmd2'}, 1],
         [{'src': '192.168.0.2', 'dst': '192.168.0.1', 'cmd': 'cmd1'}, 1]]
    

    什么是 最好的 如何做到这一点?我有一些代码示例,但没有一个是真正的好,大多数是不能正常工作。

    谢谢你的任何意见!

    更新

    TAMS评论后的最终代码是:

    from collections import namedtuple, defaultdict
    DataClass = namedtuple("DataClass", "src dst cmd")
    d1 = DataClass(src='192.168.0.1', dst='192.168.0.2', cmd='cmd1')
    d2 = DataClass(src='192.168.0.1', dst='192.168.0.2', cmd='cmd2')
    d3 = DataClass(src='192.168.0.2', dst='192.168.0.1', cmd='cmd1')
    d4 = DataClass(src='192.168.0.1', dst='192.168.0.2', cmd='cmd1')
    ds = d1, d2, d3, d4
    r = defaultdict(int)
    for d in ds:
        r[d] += 1
    print "list to compare"
    for d in ds:
        print d
    print "result after merge"
    for k, v in r.iteritems():
        print("%s: %s" % (k, v))
    
    2 回复  |  直到 16 年前
        1
  •  1
  •   Tamás    16 年前

    好吧,如果你最初的口述只包含 src , dst cmd ,您可以改用可散列的命名元组,因此可以将dict中的命名元组用作键。

    from collections import namedtuple
    
    DataClass = namedtuple("DataClass", "src dst cmd")
    d1 = DataClass(src='192.168.0.2', dst='192.168.0.1', cmd='cmd1')
    

    (对不起这个愚蠢的类名,因为我不知道你的名言代表什么,所以我想不出一个更好的名字。)你甚至可以创造 DataClass 来自dicts的实例:

    d1 = DataClass(**d1_as_dict)
    

    此时,主计数回路简化为:

    from collections import defaultdict, namedtuple
    
    r = defaultdict(int)
    for obj in [d1, d2, d3, d4]:
        r[obj] += 1
    

    如果出于某种原因,您一直在使用python<=2.5,那么 namedtuple 替换类 here .

        2
  •  1
  •   Alex Martelli    16 年前

    这个 namedtuple 是个好主意,如果可以的话。但如果你想坚持 dict 当然,这也是可能的,只是效率大大降低了。例如:

    def addadict(r, newd):
      for i, (d, count) in enumerate(r):
        if d == newd:
          r[i] = [d, count+1]
          break
      else:
        r.append([newd, 1])
    
    推荐文章