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

根据排名重新映射数据

  •  1
  • Baz  · 技术社区  · 7 年前

    我有以下几点:

    d = {"a":3,"b":2,"c":3,"d":2,"e":2,"f":3,"g":4, "h":6}
    
    m = {v: i+1 for i,v in enumerate(sorted(set(d.values()),reverse=True))}
    r = {k:m[d[k]] for k in d}  
    

    哪里 r 是:

    {'a': 3, 'd': 4, 'b': 4, 'c': 3, 'e': 4, 'f': 3, 'g': 2, 'h': 1}
    

    d 所以它被重新映射到1英寸 . 然后“g”排在第2位,因为它的第二个最高值是4英寸 D .

    我的解决方案很好,但我想知道是否有一个更优雅的解决方案。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Felipe    7 年前

    Python dicts不遵守秩序。如果你想你需要一个 OrderedDict .

    Counter 获得军衔。然后把它变成一个元组列表或者一个 订购信息 .

    from collections import Counter, OrderedDict
    
    d = {"a":3,"b":2,"c":3,"d":2,"e":2,"f":3,"g":4, "h":6}
    c = Counter(d)
    
    # if you want a list of tuples
    ranked_list = [(pair[0],rank+1) for rank,pair in enumerate(c.most_common())]
    # [('h', 1),('g', 2),('f', 3),('a', 4),('c', 5),('b', 6),('d', 7), ('e', 8)]
    
    # if you want a dict:
    ranked_dict = OrderedDict(ranked_list)
    # OrderedDict([('h', 1),('g', 2),('f', 3),('a', 4),('c', 5),('b', 6),('d', 7), ('e', 8)])
    
        2
  •  0
  •   Patrick Artner    7 年前

    您可以使用:

    d = {"a":3,"b":2,"c":3,"d":2,"e":2,"f":3,"g":4, "h":6}
    
    # sort the dictionary items by -value, throw away old value and use the
    # enumerate position starting at 1 instead - no backreferencing in the old
    # dict needed here
    
    k = {k:idx for idx,(k,_) in enumerate(sorted(d.items(), key = lambda x:-x[1]),1)}
    
    print(k)
    

    输出:

    {'h': 1, 'g': 2, 'a': 3, 'c': 4, 'f': 5, 'b': 6, 'd': 7, 'e': 8}
    
        3
  •  0
  •   Baz    7 年前
    def ranker(d):
        ranks = sorted(set(d.values()),reverse=True)
        ranks = {r:i+1 for i,r in enumerate(ranks)}
        return {k: ranks[v] for k,v in d.items()}