2

I want to know how to return values without breaking a loop in Python.

Here is an example:

def myfunction():
    list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    print(list)
    total = 0
    for i in list:
        if total < 6:
            return i  #get first element then it breaks
            total += 1
        else:
            break

myfunction()

return will only get the first answer then leave the loop, I don't want that, I want to return multiple elements till the end of that loop.

How can resolve this, is there any solution?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
Horai Nuri
  • 5,358
  • 16
  • 75
  • 127
  • you could assign it to a global/class variable, but you can't return without breaking loop that I know of –  Jan 23 '16 at 20:45
  • 2
    This seems like a highly convoluted way of doing something that should be rather simple. Could you explain what you're aiming at with your code? What is the purpose of `myfunction`? – Gabriel Jan 23 '16 at 20:47
  • @DeliriousSyntax Yes I know, but I want to know if there are some ways in order to avoid that – Horai Nuri Jan 23 '16 at 20:47
  • @Gabriel this is just an example, the real code is in Django and is too long so I didn't post it, but what you should know is that I need to return a lot a certain amount of values so `total += 1` shouldn't be ignored. – Horai Nuri Jan 23 '16 at 20:50
  • The I guess Jim's answer is what you need. – Gabriel Jan 23 '16 at 20:52

4 Answers4

9

You can create a generator for that, so you could yield values from your generator (your function would become a generator after using the yield statement).

See the topics below to get a better idea of how to work with it:

An example of using a generator:

def simple_generator(n):
    i = 0
    while i < n:
        yield i
        i += 1

my_simple_gen = simple_generator(3) # Create a generator
first_return = next(my_simple_gen) # 0
second_return = next(my_simple_gen) # 1

Also you could create a list before the loop starts and append items to that list, then return that list, so this list could be treated as list of results "returned" inside the loop.

Example of using list to return values:

def get_results_list(n):
    results = []
    i = 0
    while i < n:
        results.append(i)
        i += 1
    return results


first_return, second_return, third_return = get_results_list(3)

NOTE: In the approach with list you have to know how many values your function would return in results list to avoid too many values to unpack error

Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82
5

Using a generator is a probable way:

def myfunction():
    l = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    total = 0
    for i in l:
        if total < 6:
            yield i  #yields an item and saves function state
            total += 1
        else:
            break

g = myfunction()

Now you can access all elements returned with yield i by calling next() on it:

>>> val = next(g)
>>> print(v)
a
>>> v = next(g)
>>> print(v)
b

Or, in a for loop by doing:

>>> for returned_val in myfunction():
...    print(returned_val)
a
b
c
d
e
f
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • The question is kind of outside of what I am asking for but where should I call for `returned_val in myfunction():` in Django, in the template or in the models? – Horai Nuri Jan 23 '16 at 21:00
  • Call it when you need to use it; I really can't know your setup/what you are trying to achieve to be able to tell you more about it. – Dimitris Fasarakis Hilliard Jan 23 '16 at 21:03
2

What you want is most easily expressed with list slicing:

>>> l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>> l[:6]
# ['a', 'b', 'c', 'd', 'e', 'f']

Alternatively create another list which you will return at the end of the function.

def myfunction():
    l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
    ret = []

    total = 0
    for i in l:
        if total < 6:
            total += 1
            ret.append(i)

    return ret

myfunction()

# ['a', 'b', 'c', 'd', 'e', 'f']
jumbopap
  • 3,969
  • 5
  • 27
  • 47
0

A yield statement to create a generator is what you want.

What does the "yield" keyword do in Python?

Then use the next method to get each value returned from the loop.

var = my_func().next()
Community
  • 1
  • 1
BenJ
  • 456
  • 2
  • 7