基于计数器递增 Python 字典值

Incrementing Python Dictionary Value based on a Counter

我有一个包含重复值的字典。

Deca_dict = {
    "1": "2_506",
    "2": "2_506",
    "3": "2_506",
    "4": "2_600",
    "5": "2_600",
    "6": "1_650"
}

我已经用collections.Counter算出了每一种有多少。

decaAdd_occurrences = {'2_506':3, '2_600':2, '1_650':1}

然后我创建了一个新的要更新的值字典。

deca_double_dict = {key: value for key, value in Deca_dict.items()
                        if decaAdd_occurrences[value] > 1}
deca_double_dict = {
    "1": "2_506",
    "3": "2_506",
    "2": "2_506",
    "4": "2_600"
}

(在这种情况下,它是没有最后一项的原始字典)

我想弄清楚如何增加 num,使 counter_dict 的值减 1。这将更新除一个值之外的所有值,该值可以保持不变。 目标输出允许其中一个重复值保持相同的值,而其余的值字符串的第一个数字将逐渐递增(基于重复计数的数量)。我正在尝试为原始 Deca_dict.

表示的数据实现唯一值
Goal output = {'1':'3_506', '2':'4_506', '3':'2_506', '4':'3_600', '5':'2_600'}

我开始按照以下方式处理事情,但最终只是递增所有双项,结果是我原来的结果,除了值加一。 对于上下文:原始 Deca_dict 的值被发现连接两个数字(deca_address_num 和 deca_num_route)。此外,homeLayer 是一个 QGIS 矢量图层,其中 deca_address_num 和 deca_num_route 存放在索引为 d_address_idx 和 id_route_idx.

的字段中
for key in deca_double_dict.keys():
    for home in homesLayer.getFeatures():
        if home.id() == key:
            deca_address_num = home.attributes()[d_address_idx]
            deca_num_route = home.attributes()[id_route_idx]
            deca_address_plus = deca_address_num + increment
            next_deca_address = (str(deca_address_plus) + '_' +
                                 str(deca_num_route))
            if not next_deca_address in Deca_dict.values():
                update_deca_dbl_dict[key] = next_deca_address

结果没用:

Update_deca_dbl_dict = {
    "1": "3_506",
    "3": "3_506",
    "2": "3_506",
    "5": "3_600",
    "4": "3_600"
}

我第二次尝试添加一个计数器,但放错了地方。

for key, value in deca_double_dict.iteritems():
    iterations = decaAdd_occurrences[value] - 1
    for home in homesLayer.getFeatures():
        if home.id() == key:
            #deca_homeID_list.append(home.id())
            increment = 1
            deca_address_num = home.attributes()[d_address_idx]
            deca_num_route = home.attributes()[id_route_idx]
            deca_address_plus = deca_address_num + increment
            next_deca_address = (str(deca_address_plus) + '_' +
                                 str(deca_num_route))
            #print deca_num_route
            while iterations > 0:
                if not next_deca_address in Deca_dict.values():
                    update_deca_dbl_dict[key] = next_deca_address
                    iterations -= 1
                    increment += 1

UPDATE 尽管下面的答案之一适用于递增我字典中的所有重复项,但我正在尝试重新编写我的代码,因为我需要进行此比较条件对原始数据进行递增。我仍然得到与第一次尝试相同的结果(没用的那个)。

for key, value in deca_double_dict.iteritems():
    for home in homesLayer.getFeatures():
        if home.id() == key:
            iterations = decaAdd_occurrences[value] - 1
            increment = 1
            while iterations > 0:
                deca_address_num = home.attributes()[d_address_idx]
                deca_num_route = home.attributes()[id_route_idx]
                deca_address_plus = deca_address_num + increment
                current_address = str(deca_address_num) + '_' + str(deca_num_route)
                next_deca_address = (str(deca_address_plus) + '_' +
                                 str(deca_num_route))
                if not next_deca_address in Deca_dict.values():
                    update_deca_dbl_dict[key] = next_deca_address
                    iterations -= 1
                    increment += 1
                else:
                    alpha_deca_dbl_dict[key] = current_address
                    iterations = 0

这大概就是您想要的吗?我假设您可以处理将 2_506 更改为 3_506 等的功能。我使用一个集合来确保没有重复值,而不是您的计数器。

原文post我在最下面截了一行,不好意思。

values_so_far = set()
d1 = {} # ---your original dictionary with duplicate values---
d2 = {} # d1 with all the duplicates changed
def increment_value(old_value):
    # you know how to write this
    # return the modified string

for k,v in d1.items():
    while v in values_so_far:
        v = increment_value(v)
    d2[k] = v
    values_so_far.add(v)

解决方法如下: 本质上,它保留第一个重复值并增加其余重复值的前置数字。

from collections import OrderedDict, defaultdict
orig_d = {'1':'2_506', '2':'2_506', '3':'2_506', '4':'2_600', '5':'2_600'}
orig_d = OrderedDict(sorted(orig_d.items(), key=lambda x: x[0]))

counter = defaultdict(int)
for k, v in orig_d.items():
    counter[v] += 1
    if counter[v] > 1:
        pre, post = v.split('_')
        pre = int(pre) + (counter[v] - 1)
        orig_d[k] = "%s_%s" % (pre, post)

print(orig_d)

结果:

OrderedDict([('1', '2_506'), ('2', '3_506'), ('3', '4_506'), ('4', '2_600'), ('5', '3_600')])

我想这就是你想要的。我稍微修改了您的输入字典以更好地说明发生了什么。与您所做的一个主要区别是 decaAdd_occurrences,它是从 Counter 字典创建的,它不仅跟踪计数,还跟踪当前地址 num 前缀的值.这使得知道下一个要使用的 num 值成为可能,因为它和计数都在修改 Deca_dict.

的过程中更新了
from collections import Counter

Deca_dict = {
    "1": "2_506",
    "2": "2_506",
    "3": "2_506",
    "4": "2_600",
    "5": "1_650",
    "6": "2_600"
}

decaAdd_occurrences = {k: (int(k.split('_')[0]), v) for k,v in
                                Counter(Deca_dict.values()).items()}

for key, value in Deca_dict.items():
    num, cnt = decaAdd_occurrences[value]
    if cnt > 1:
        route = value.split('_')[1]
        next_num = num + 1
        Deca_dict[key] = '{}_{}'.format(next_num, route)
        decaAdd_occurrences[value] = next_num, cnt-1  # update values

更新字典:

Deca_dict -> {
    "1": "3_506",
    "2": "2_506",
    "3": "4_506",
    "4": "3_600",
    "5": "1_650",
    "6": "2_600"
}