Python字典 - 比较值

时间:2015-09-30 21:33:03

标签: python arrays json sorting parsing

问题是如何根据最大值和最小值按键提取值解析字典。然后比较其中的值,并根据计算添加一些键值。也许问题很混乱,但我会用代码提供更多解释。

json对象

[
    {
        "YCI": 0.014076729909151329,
        "TCI": 0.5610661498232027,
        "FCI": 0.327632092582722,
        "TFCI": 3.04906430661623,
        "naziv": "HDZ",
        "YCSI": 14.49723089452966
    },
    {
        "YCI": 0.04249999676677044,
        "TCI": 0.33129318126147167,
        "FCI": 1.677073944380761,
        "TFCI": 4.326953034001479,
        "naziv": "HNS",
        "YCSI": 56.80909574468085
    },
    {
        "YCI": 0,
        "TCI": 0.40603351151808614,
        "FCI": 0,
        "TFCI": 12.61045547126369,
        "naziv": "HSP AS",
        "YCSI": 0
    },
    {
        "YCI": 2.231205214448367,
        "TCI": 0,
        "FCI": 0,
        "TFCI": 0,
        "naziv": "HSS",
        "YCSI": 949.343111111111
    }
]

好的,这是我的字典。现在如何比较字典中的键:

  • YCI
  • TCI
  • FCI
  • TFCI
  • naziv
  • YSCI

彼此根据他们的价值观。如果值YCI具有最高值然后是YCI,则它应该在新字典中设置数字1,并且该逻辑也应用于字典中的其他键。 输出将类似于:

JSON输出

  [
    {
        "YCI": 3,
        "TCI": 1,
        "FCI": 2,
        "TFCI": 3,
        "naziv": "HDZ",
        "YCSI": 3
    },
    {
        "YCI": 2,
        "TCI": 3,
        "FCI": 1,
        "TFCI": 2,
        "naziv": "HNS",
        "YCSI": 2
    },
    {
        "YCI": 0,
        "TCI": 2,
        "FCI": 0,
        "TFCI": 1,
        "naziv": "HSP AS",
        "YCSI": 0
    },
    {
        "YCI": 1,
        "TCI": 0,
        "FCI": 0,
        "TFCI": 0,
        "naziv": "HSS",
        "YCSI": 1
    }
]

最高值得到数字1,最低值取决于字典包含的对象数量。

代码试

print max(nvalues[0].iteritems(), key=operator.itemgetter(1))[1]

使用此代码,我可以提取最高值,但如何在其值中对字典进行排序。如果你能给我一些逻辑来解决这个问题,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

def rank_by_value(list_dicts):

    from operator import  itemgetter
    from itertools import groupby

    nums = []
    symbs = []

    # separting keys, values into two lists
    # one for numeric values, the other for string values
    for indx, d in enumerate(list_dicts):
        for k, val in d.items():
            if type(val) in (int,float):
                nums.append((indx,k,val))
            else:
                symbs.append((indx,{k:val}))

    groups = []
    # grouping lists
    for k, g in groupby(nums, key=itemgetter(0)):
        groups.append(list(g))

    allData = []
    # sorting lists by by each dictionry values and assinging ranks
    for g in groups:
        sort_ed = sorted(g, key=itemgetter(2), reverse=True)
        ranked = [ list((t,i+1)) for i,t in enumerate(sort_ed)]
        allData.append(ranked)
        ranked = []

    # remove numerical data
    for zero in allData:
        for i, el in enumerate(zero):
           one,two, _ = el[0]
           zero[i] = one,(two, el[1])

    # now creating dictionaries anew
    list_of_dict = []
    dict_temp = {}

    for i, (el, sy) in enumerate(zip(allData, symbs)) :
        for l in el:
            name_, rank_ = l[1]
            dict_temp[name_] = rank_
        dict_temp.update(symbs[i][1])
        list_of_dict.append(dict_temp)
        dict_temp = {}



    return list_of_dict



 for el in rank_by_value(jsn):
    print(el)


{'TCI': 3, 'YCSI': 1, 'naziv': 'HDZ', 'YCI': 5, 'FCI': 4, 'TFCI': 2}
{'TCI': 4, 'YCSI': 1, 'naziv': 'HNS', 'YCI': 5, 'FCI': 3, 'TFCI': 2}
{'TCI': 2, 'YCSI': 3, 'naziv': 'HSP AS', 'YCI': 4, 'FCI': 5, 'TFCI': 1}
{'TCI': 3, 'YCSI': 1, 'naziv': 'HSS', 'YCI': 2, 'FCI': 4, 'TFCI': 5}

答案 1 :(得分:0)

import six

raw_object = [
    {
        "YCI": 0.014076729909151329,
        "TCI": 0.5610661498232027,
        "FCI": 0.327632092582722,
        "TFCI": 3.04906430661623,
        "naziv": "HDZ",
        "YCSI": 14.49723089452966
    },
    {
        "YCI": 0.04249999676677044,
        "TCI": 0.33129318126147167,
        "FCI": 1.677073944380761,
        "TFCI": 4.326953034001479,
        "naziv": "HNS",
        "YCSI": 56.80909574468085
    },
    {
        "YCI": 0,
        "TCI": 0.40603351151808614,
        "FCI": 0,
        "TFCI": 12.61045547126369,
        "naziv": "HSP AS",
        "YCSI": 0
    },
    {
        "YCI": 2.231205214448367,
        "TCI": 0,
        "FCI": 0,
        "TFCI": 0,
        "naziv": "HSS",
        "YCSI": 949.343111111111
    }
]

#make a list (equal in length to original object) of empty dictionaries
ranks_object = [{} for i in raw_object]

#iterate through each key in the first dictionary
#(I assumed that all dictionaries will have the same keys)
for key in raw_object[0]:

    #create a list with the value for this key from all dictionaries 
    raw_list = [group[key] for group in raw_object]

    #sort and store the list
    sorted_raw_list = sorted(raw_list)

    #create a list of the ranks of each of the raw values
    #if the value is greater than zero, a value's rank is the length
    #  of the raw list minus the index of the value in the sorted list
    #otherwise, the rank should be 0 (as indicated by OP's desired output)
    ranks = [len(raw_list) - sorted_raw_list.index(value) if value > 0 else 0 for value in raw_list]

    #iterate through each rank in the ranks list (with access to the
    #  list index, which will be used to make sure that the rank is
    #  inserted into the proper dictionary)
    for index, rank in enumerate(ranks):

        #if the value for the key in the first dictionary is a string,
        #  insert the original value with the key
        #(I assumed that if one dictionary has a string value for a
        #  certain key, all of the dictionaries do as well)
        if isinstance(raw_object[0][key], six.string_types):
            ranks_object[index][key] = raw_object[index][key]

        #otherwise insert the rank with the key
        else:
            ranks_object[index][key] = rank

#display each rank dictionary separately to improve readability
for x in ranks_object:
    print x