使用同一字典中的键扩展字典值
Expanding dict value using keys in the same dictionary
我尝试使用同一字典中的键来扩展字典的值。换句话说,我尝试替换 dic
值(现有集合与另一个/可能扩展的集合)。当值包含字典中的键时会发生扩展。
输入:
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
预期输出:
{
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '01', '02'},
'21': {'06', '03', '04'},
'30': {'07', '05', '01', '02'},
'40': {'08', '06', '03', '04', '07', '05', '01', '02'},
'50': {'09', '08', '06', '03', '04', '07', '05', '01', '02'}
}
我正在尝试创建一个递归函数...
def transform_dic(d):
def func(k):
v = d.get(k, k)
if v != k:
for e in v:
v = func(v)
return v
d2 = {}
for k, v in d.items():
d2[k] = {func(i) for i in v}
return d2
print(transform_dic(dic))
TypeError: unhashable type: 'set'
您可以迭代输出字典并检查集合中的值是否是结果字典的成员:
from typing import Dict, Set
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
output = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '01', '02'},
'21': {'06', '03', '04'},
'30': {'07', '05', '01', '02'},
'40': {'08', '06', '03', '04', '07', '05', '01', '02'},
'50': {'09', '08', '06', '03', '04', '07', '05', '01', '02'}
}
def conv(d: Dict[str, set[str]]) -> Dict[str, set[str]]:
result: Dict[str, set[str]] = {}
for k,vs in d.items():
result[k] = set()
for v in vs:
if v in result:
for t in result[v]:
result[k].add(t)
else:
result[k].add(v)
return result
print(conv(dic))
print(conv(dic)==output)
输出将是
{'10': {'02', '01'}, '11': {'03', '04'}, '20': {'02', '05', '01'}, '21': {'06', '03', '04'}, '30': {'02', '05', '07', '01'}, '40': {'05', '03', '02', '01', '06', '07', '08', '04'}, '50': {'05', '03', '09', '02', '01', '06', '07', '08', '04'}}
True
你要递归展开的是字典中的集合,而不是字典本身。你永远只有一个字典。
出于这个原因,我认为编写一个递归函数来扩展一个集合,然后使用这个函数来扩展字典会更容易。
def expanded_dict(d):
return {k: expanded_set(v, d) for k,v in d.items()}
def expanded_set(s, d):
return {
y
for x in s
for y in (expanded_set(d[x], d) if x in d
else (x,))
}
注意 expanded_set
returns 一个新的集,没有修改输入集和输入字典;和 expanded_dict
returns 一个不修改输入字典的新字典。
最好明确说明您的函数 returns 是新对象还是修改输入对象。例如,sorted
returns 一个新列表而不修改其输入,而 list.sort
修改一个列表而不返回任何内容。
这是一个通过修改字典而不返回任何内容来扩展字典的函数:
def expand_dict(d):
stable = False
while not stable:
stable = True
for k in d:
for x in list(d[k]):
if x in d:
d[k].remove(x)
d[k].update(d[x])
stable = False
正在使用您的示例进行测试:
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
print(expanded_dict(dic))
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'01', '05', '02'}, '21': {'03', '06', '04'}, '30': {'07', '01', '02', '05'}, '40': {'04', '06', '08', '05', '02', '01', '07', '03'}, '50': {'04', '06', '08', '02', '05', '01', '07', '09', '03'}}
print(dic)
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'10', '05'}, '21': {'11', '06'}, '30': {'07', '20'}, '40': {'08', '30', '21'}, '50': {'40', '09'}}
expand_dict(dic)
# no return value
print(dic)
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'01', '02', '05'}, '21': {'03', '06', '04'}, '30': {'01', '05', '07', '02'}, '40': {'04', '06', '08', '05', '02', '01', '07', '03'}, '50': {'04', '06', '08', '05', '02', '01', '07', '09', '03'}}
一定要递归吗?
def transform_dic(d):
for k, v in d.items():
for n in set(v):
if n in d:
d[k].remove(n)
d[k].update(d[n])
transform_dic(dic)
print(dic)
如果您不想修改原始词典,请使用deepcopy
def transform_dic(d):
d = deepcopy(d)
for k, v in d.items():
for n in set(v):
if n in d:
d[k].remove(n)
d[k].update(d[n])
return d
print(transform_dic(dic))
输出:
{
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'01', '05', '02'},
'21': {'03', '04', '06'},
'30': {'01', '07', '05', '02'},
'40': {'01', '08', '07', '04', '06', '03', '05', '02'},
'50': {'01', '08', '07', '04', '06', '03', '05', '02', '09'}
}
我尝试使用同一字典中的键来扩展字典的值。换句话说,我尝试替换 dic
值(现有集合与另一个/可能扩展的集合)。当值包含字典中的键时会发生扩展。
输入:
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
预期输出:
{
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '01', '02'},
'21': {'06', '03', '04'},
'30': {'07', '05', '01', '02'},
'40': {'08', '06', '03', '04', '07', '05', '01', '02'},
'50': {'09', '08', '06', '03', '04', '07', '05', '01', '02'}
}
我正在尝试创建一个递归函数...
def transform_dic(d):
def func(k):
v = d.get(k, k)
if v != k:
for e in v:
v = func(v)
return v
d2 = {}
for k, v in d.items():
d2[k] = {func(i) for i in v}
return d2
print(transform_dic(dic))
TypeError: unhashable type: 'set'
您可以迭代输出字典并检查集合中的值是否是结果字典的成员:
from typing import Dict, Set
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
output = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '01', '02'},
'21': {'06', '03', '04'},
'30': {'07', '05', '01', '02'},
'40': {'08', '06', '03', '04', '07', '05', '01', '02'},
'50': {'09', '08', '06', '03', '04', '07', '05', '01', '02'}
}
def conv(d: Dict[str, set[str]]) -> Dict[str, set[str]]:
result: Dict[str, set[str]] = {}
for k,vs in d.items():
result[k] = set()
for v in vs:
if v in result:
for t in result[v]:
result[k].add(t)
else:
result[k].add(v)
return result
print(conv(dic))
print(conv(dic)==output)
输出将是
{'10': {'02', '01'}, '11': {'03', '04'}, '20': {'02', '05', '01'}, '21': {'06', '03', '04'}, '30': {'02', '05', '07', '01'}, '40': {'05', '03', '02', '01', '06', '07', '08', '04'}, '50': {'05', '03', '09', '02', '01', '06', '07', '08', '04'}}
True
你要递归展开的是字典中的集合,而不是字典本身。你永远只有一个字典。
出于这个原因,我认为编写一个递归函数来扩展一个集合,然后使用这个函数来扩展字典会更容易。
def expanded_dict(d):
return {k: expanded_set(v, d) for k,v in d.items()}
def expanded_set(s, d):
return {
y
for x in s
for y in (expanded_set(d[x], d) if x in d
else (x,))
}
注意 expanded_set
returns 一个新的集,没有修改输入集和输入字典;和 expanded_dict
returns 一个不修改输入字典的新字典。
最好明确说明您的函数 returns 是新对象还是修改输入对象。例如,sorted
returns 一个新列表而不修改其输入,而 list.sort
修改一个列表而不返回任何内容。
这是一个通过修改字典而不返回任何内容来扩展字典的函数:
def expand_dict(d):
stable = False
while not stable:
stable = True
for k in d:
for x in list(d[k]):
if x in d:
d[k].remove(x)
d[k].update(d[x])
stable = False
正在使用您的示例进行测试:
dic = {
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'05', '10'},
'21': {'06', '11'},
'30': {'07', '20'},
'40': {'08', '21', '30'},
'50': {'09', '40'}
}
print(expanded_dict(dic))
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'01', '05', '02'}, '21': {'03', '06', '04'}, '30': {'07', '01', '02', '05'}, '40': {'04', '06', '08', '05', '02', '01', '07', '03'}, '50': {'04', '06', '08', '02', '05', '01', '07', '09', '03'}}
print(dic)
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'10', '05'}, '21': {'11', '06'}, '30': {'07', '20'}, '40': {'08', '30', '21'}, '50': {'40', '09'}}
expand_dict(dic)
# no return value
print(dic)
# {'10': {'01', '02'}, '11': {'03', '04'}, '20': {'01', '02', '05'}, '21': {'03', '06', '04'}, '30': {'01', '05', '07', '02'}, '40': {'04', '06', '08', '05', '02', '01', '07', '03'}, '50': {'04', '06', '08', '05', '02', '01', '07', '09', '03'}}
一定要递归吗?
def transform_dic(d):
for k, v in d.items():
for n in set(v):
if n in d:
d[k].remove(n)
d[k].update(d[n])
transform_dic(dic)
print(dic)
如果您不想修改原始词典,请使用deepcopy
def transform_dic(d):
d = deepcopy(d)
for k, v in d.items():
for n in set(v):
if n in d:
d[k].remove(n)
d[k].update(d[n])
return d
print(transform_dic(dic))
输出:
{
'10': {'01', '02'},
'11': {'03', '04'},
'20': {'01', '05', '02'},
'21': {'03', '04', '06'},
'30': {'01', '07', '05', '02'},
'40': {'01', '08', '07', '04', '06', '03', '05', '02'},
'50': {'01', '08', '07', '04', '06', '03', '05', '02', '09'}
}