How to Format Lists of Strings and Dictionaries for Email Body in Python

101 Views Asked by At

I'm working on a Python script where I need to format three different types of lists into a string that will be used as the body of an email. The lists are as follows:

A list of strings:

a = ['1.1.1.1', '2.2.2.2', '3.3.3.3']

A list of dictionaries, each containing a single key-value pair:

b = [{'IP': '1.1.1.1'}, {'IP': '2.2.2.2'}, {'IP': '3.3.3.3'}]

A list of dictionaries with multiple key-value pairs:

c = [{'ID': 'dasfsdfs', 'IP': '1.1.1.1', 'Name': 'me'}, {'ID': 'qwrfgvzx', 'IP': '2.2.2.2', 'Name': 'you'}]

I want to format these lists so that each element (or key-value pair) appears on a separate line in the email body. Here's the structure I'm aiming for:

a_var -->
1.1.1.1
2.2.2.2
3.3.3.3

b_var -->
IP: 1.1.1.1
IP: 2.2.2.2
IP: 3.3.3.3

c_var -->
ID: dasfsdfs
IP: 1.1.1.1
Name: me

ID: qwrfgvzx
IP: 2.2.2.2
Name: you

I'm attempting to use inline for loops within an f-string to create this formatted string, but I'm not sure how to correctly apply this for each list, especially for the list of dictionaries with multiple key-value pairs.

my_email = f'''
a_var -->\n{inline for loop for {a}}

b_var -->\n{inline for loop for {b}}

c_var -->\ninline for loop for {c}}
'''

Can anyone suggest the correct way to achieve this formatting in Python?

2

There are 2 best solutions below

0
str1ng On BEST ANSWER

Assuming that you want output like this:

a_var -->
1.1.1.1
2.2.2.2
3.3.3.3

b_var -->
IP: 1.1.1.1
IP: 2.2.2.2
IP: 3.3.3.3

c_var -->
ID: dasfsdfs
IP: 1.1.1.1
Name: me

ID: qwrfgvzx
IP: 2.2.2.2
Name: you

For List a:

  • This list "a" would contain '1.1.1.1', '2.2.2.2', etc.
  • To achieve that: you're joining the strings with a new line char \n - basically it's like you are manually pressing enter each time.

For List b:

  • This one is the one which contains dictionary, each which has "IP" key
  • To achieve that: going through each dict with "IP" key, you then write it as "IP" followed by key, again you're at the end joining it with new line char.

For List c:

  • This one represents dictionary again, but now it's with multiple key values (ID, IP, Name).
  • To achieve that: Well, this one is a bit of harder one assuming that you're new to python, you are going to loop through each dict in list,.inside that loop you're going again through each key-value pair in it, you're combining them and joining them, but this time you're basically adding extra new line char, why? Because this is assuring that there's blank line between each set of ID, IP and Name.

To give you an idea:

a = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
b = [{'IP': '1.1.1.1'}, {'IP': '2.2.2.2'}, {'IP': '3.3.3.3'}]
c = [{'ID': 'dasfsdfs', 'IP': '1.1.1.1', 'Name': 'me'}, {'ID': 'qwrfgvzx', 'IP': '2.2.2.2', 'Name': 'you'}]

a_formatted = '\n'.join(a)

b_formatted = '\n'.join([f"IP: {d['IP']}" for d in b])

c_formatted = '\n\n'.join(['\n'.join([f"{k}: {v}" for k, v in d.items()]) for d in c])

formatted_email = f'''
a_var -->
{a_formatted}

b_var -->
{b_formatted}

c_var -->
{c_formatted}
'''

print(formatted_email)
3
Timeless On

Why not use jinja's templates in which you can incorporate loops ?

You can make a Template, shape it the way you want and finally render it :

# pip install Jinja2
from jinja2 import Template

text = """
a_var -->
{% for obj in a -%}
{{ obj }}
{% endfor %}
b_var -->
{% for obj in b -%}
{% for k, v in obj.items() -%}
{{ k }}: {{ v }}
{% endfor -%}
{% endfor %}
c_var -->
{% for obj in c -%}
{% for k, v in obj.items() -%}
{{ k }}: {{ v }}
{% endfor %}
{% if not loop.last %}{% endif %}{% endfor %}
"""

tpl = Template(text).render(a=a, b=b, c=c)

Output :

a_var -->
1.1.1.1
2.2.2.2
3.3.3.3

b_var -->
IP: 1.1.1.1
IP: 2.2.2.2
IP: 3.3.3.3

c_var -->
ID: dasfsdfs
IP: 1.1.1.1
Name: me

ID: qwrfgvzx
IP: 2.2.2.2
Name: you