Search code examples
pythonf-string

Converting a list of strings into part of a f string in Python


I have a list of error messages:

errors = [
    "this is an error",
    "this is another error",
]

I am then sending this as an email using Amazon SES:

ses_client.send_email(
        Destination={
            "ToAddresses": [
                "[email protected]",
            ],
        },
        Message={
            "Subject": {
                "Charset": "UTF-8",
                "Data": "Processed tracking file",
            },
            "Body": {
                "Text": {
                    "Charset": "UTF-8",
                    "Data": f"Finished Processing tracking file\n\n"
                            f"Sent {NUM_OF_EMAILS} emails"
                            f"\n".join(ERRORS)
                }
            },
        },
        Source="[email protected]",
    )

However, this seems to mess up the fString with the first error being the first line of the message, then the Finished Processing tracking file bit followed by the remaining errors.

Is there a cleaner way to do this?


Solution

  • Implicit string joining only apples to string literals, not arbitrary str-valued expressions. The three string literals involved here are

    1. f"Finished Processing tracking file\n\n"
    2. f"Sent {NUM_OF_EMAILS} emails"
    3. f'\n'

    These are implicitly joined into a single str value; that string is the one that invokes the join method on ERRORS, not just the f'\n' you intended.

    Since you want to join the first two strings to the result of the call to str.join, you need something like

    ...
    "Data": f"Finished Processing tracking file\n\n"
            f"Sent {NUM_OF_EMAILS} emails" + 
            f"\n".join(ERRORS)
    ...
    

    to implicitly join the first two strings before explicitly joining the result with the return value of f'\n'.join(ERRORS).

    I would recommend avoiding implicit string joining altogether, and be explicit about what strings you want to join:

    ...
    "Data": "Finished Processing tracking file\n\n"
            + f"Sent {NUM_OF_EMAILS} emails" 
            + "\n".join(ERRORS)
    ...
    

    (and only use f-string literals when you need them).