[Django]-Looping through to create a tuple

4👍

If I understand correctly, this is pretty simple with a comprehension.

emails = [
    (u'Subject', u'Message.', u'from@example.com', [address])
    for name, address in recipients
]
send_mass_mail(emails)

Note that we leverage Python’s ability to unpack tuples into a set of named variables. For each element of recipients, we assign its zeroth element to name and its first element to address. So in the first iteration, name is u'John' and address is u'john@example.com'.

If you need to vary the 'Message.' based on the name, you can use string formatting or any other formatting/templating mechanism of your choice to generate the message:

emails = [
    (u'Subject', u'Dear {}, Message.'.format(name), u'from@example.com', [address])
    for name, address in recipients
]

Since the above are list comprehensions, they result in emails being a list. If you really need this to be a tuple instead of a list, that’s easy, too:

emails = tuple(
    (u'Subject', u'Message.', u'from@example.com', [address])
    for name, address in recipients
)

For this one, we’re actually passing a generator object into the tuple constructor. This has the performance benefits of using a generator without the overhead of creating an intermediate list. You can do that pretty much anywhere in Python where an iterable argument is accepted.

👤jpmc26

1👍

Just a little bit of cleanup needed here:

1) actually build the tuple in the loop (this is a bit tricky since you need the extra comma to ensure that a tuple is appended and not the values from the tuple)

2) move the send_mass_mail call outside the loop

This should be working code:

recipients = notification.objects.all().values_list('username','email')
# this returns [(u'John', u'john@example.com'), (u'Jane', u'jane@example.com')]
datatuple = []
for recipient in recipients:    
    to = recipient[1]               #access the email
    subject = "my big tuple loop"
    dear = recipient[0]              #access the name  
    message = "This concerns tuples!"
    #### add each recipient to datatuple
    datatuple.append((subject, message, "from@example.com", [to,]),)
send_mass_mail(tuple(datatuple))

EDIT:
jpmc26’s technique is definitely more efficient, and if you’re planning to have a large email list to send to you should use that. Most likely you should use whichever code makes the most sense to you personally so that when your requirements change you can easily understand how to update.

Leave a comment