How can I use `return` to get back multiple values from a loop? Can I put them in a list?

Question:

I have some code that prints data from a global dictionary named cal:

def show_todo():
    for key, value in cal.items():
        print(value[0], key)

However, I want to use this code as part of a Discord bot. In order for the bot to work properly, I need to return the data to another function that will actually send the message to the Discord chat. Using print like above means that the message is displayed in my local console window, and the chat just sees None.

I tried to fix it by using return instead:

def show_todo():
    for key, value in cal.items():
        return(value[0], key)

but this way, the for loop does not work properly. I only get at most one key-value pair from the dictionary.

How can I fix this so that all of the data is returned?

Asked By: Eric.L

||

Answers:

Use a generator syntax (excellent explanation on SO here):

def show_todo():
    for key, value in cal.items():
        yield value[0], key

for value, key in show_todo():
    print(value, key)
Answered By: Uriel

Using a return inside of a loop will break it and exit the function even if the iteration is still not finished.

For example:

def num():
    # Here there will be only one iteration
    # For number == 1 => 1 % 2 = 1
    # So, break the loop and return the number
    for number in range(1, 10):
        if number % 2:
            return number
>>> num()
1

In some cases we need to break the loop if some conditions are met. However, in your current code, breaking the loop before finishing it is unintentional.

Instead of that, you can use a different approach:

Yielding your data

def show_todo():
    # Create a generator
    for key, value in cal.items():
        yield value[0], key

You can call it like:

a = list(show_todo())  # or tuple(show_todo())

or you can iterate through it:

for v, k in show_todo(): ...

Putting your data into a list or other container

Append your data to a list, then return it after the end of your loop:

def show_todo():
    my_list = []
    for key, value in cal.items():
        my_list.append((value[0], key))
    return my_list

Or use a list comprehension:

def show_todo():
    return [(value[0], key) for key, value in cal.items()]
Answered By: Chiheb Nexus
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.