基于计数器递增 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"
}
我有一个包含重复值的字典。
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"
}