Просто используйте форматирование строки Python и разверните в качестве аргументов d1
dict:
d1={'A':'x', 'B':'y', 'C':'{A}_foo', 'D':'bar_{B}'}
d2={k:v.format(v,**d1) for k,v in d1.items()}
>>> d2
{'A': 'x', 'B': 'y', 'C': 'x_foo', 'D': 'bar_y'}
Однако здесь есть потенциал ключевых ошибок. Обратите внимание:
>>> d1={'A':'x', 'B':'y', 'C':'{A}_foo', 'D':'bar_{B}', 'E':'no-key_{Z}'}
>>> d2={k:v.format(v,**d1) for k,v in d1.items()}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <dictcomp>
KeyError: 'Z'
Если вы хотите корректно обрабатывать ключевые ошибки, вы можете создать подкласс Formatter следующим образом:
import string
class PartialFormatter(string.Formatter):
def __init__(self, missing='~~', bad_fmt='!!'):
self.missing, self.bad_fmt=missing, bad_fmt
def get_field(self, field_name, args, kwargs):
# Handle a key not found
try:
val=super(PartialFormatter, self).get_field(field_name, args, kwargs)
# Python 3, 'super().get_field(field_name, args, kwargs)' works
except (KeyError, AttributeError):
val=None,field_name
return val
def format_field(self, value, spec):
# handle an invalid format
if value==None: return self.missing
try:
return super(PartialFormatter, self).format_field(value, spec)
except ValueError:
if self.bad_fmt is not None: return self.bad_fmt
else: raise
d1={'A':'x', 'B':'y', 'C':'{A}_foo', 'D':'bar_{B}', 'E':'no-key_{Z}'}
d2={}
fmt=PartialFormatter()
for k,v in d1.items():
if '{' in v:
d2[k]=fmt.format(v,**d1)
else:
d2[k]=v
Тогда вы просто молча получаете ~~
вместо KeyError
:
>>> d2
{'A': 'x', 'B': 'y', 'C': 'x_foo', 'D': 'bar_y', 'E': 'no-key_~~'}
Который может быть изменен в соответствии с желаемым вами поведением ...
Или, что еще лучше, используйте try / except
:
d1={'A':'x', 'B':'y', 'C':'{A}_foo', 'D':'bar_{B}', 'E':'bad-fmt_{:B}', 'F':'no-key_{Z}'}
d2={}
for k,v in d1.items():
if '{' in v:
try:
d2[k]=v.format(v,**d1)
except (KeyError, ValueError):
d2[k]=v
else:
d2[k]=v
>>> d2
{'A': 'x', 'B': 'y', 'C': 'x_foo', 'D': 'bar_y', 'E': 'bad-fmt_{:B}', 'F': 'no-key_{Z}'}