Formatting a string in Python with three possible replacement fields I'm looking for a much simpler way of formatting a string in Python which will have a different number of replacement fields in different cases. Here's what I'm doing now, which is working fine:

if '{yes}' in reply and '{value}' in reply:
    reply = reply.format(yes=get_yes(), value=value)
elif '{no}' in reply and '{value}' in reply:
    reply = reply.format(no=get_no(), value=value)
elif '{yes}' in reply:
    reply = reply.format(yes=get_yes())
elif '{no}' in reply:
    reply = reply.format(no=get_no())
elif '{value}' in reply:
    reply = reply.format(value=value)


The only problem is that this code has a Cognitive Complexity of 11 on Code Climate, which is higher than the allowed value of 5, and so I'm trying to find out a way of reducing it.

Additional information about variables and methods


reply is a string with will have one of the following combinations of replacement fields:


{yes} and {value}
{no} and {value}
{yes} only
{no} only
{value} only
no replacement field

get_yes() randomly returns a string that has the same meaning as "yes" ("yeah", "yep" etc.)
get_no() randomly returns a string that has the same meaning as "no" ("nah", "nope" etc.)
value is a numeric value (integer or float)
Build a kwargs dictionary, rather than using an if-else.
You don't have to treat yes and no as mutually exclusive.
You could use a 'key, function' list to create a dictionary comprehension that builds the dictionary for you.


This can lead to:

kwargs = {}
if '{value}' in reply:
    kwargs['value'] = value
if '{yes}' in reply:
    kwargs['yes'] = get_yes()
if '{no}' in reply:
    kwargs['no'] = get_no()
reply = reply.format(**kwargs)




params = [
    ('value', lambda:value),
    ('yes', get_yes),
    ('no', get_no)
]

def format_format(format, params):
    return format.format({
        key: fn()
        for key, fn in params
        if f'{{{key}}}' in format
    })

reply = format_format(reply, params)