-4

Let's say,

def sample():
    if a==1:
        print(a)
    else:
        continue

for i in language:
    a=i
    sample()

I want to use this function in a loop, but the continue command gives me an error because there is no loop. What can I do?

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    Because `sample` doesn't have a loop. `continue` is used to skip to the next iteration, what exactly do you expect it to do there even if there was a loop? – Guy Sep 13 '22 at 12:04
  • 1
    `continue` & `break` can only be used inside loops within the same scope (function). Rethink your code. – rdas Sep 13 '22 at 12:05
  • Correct, you can't put it in a function. It must be in a loop – SiHa Sep 13 '22 at 12:06
  • 1
    The function should have the `a` parameter, besides that `continue` wouldn't do anything in this case – XxJames07- Sep 13 '22 at 12:08
  • The placement of the call to `sample()` in the for loop means that any `continue` is redundant. Please explain what you want to achieve. – quamrana Sep 13 '22 at 12:12
  • guys I explained in the question, I am doing a few operations inside the loop. If the state inside my function is not provided, I want my loop to pass to the next element and that's it. – Ahmet Said Oyanık. Sep 13 '22 at 12:29
  • You cannot use `continue` like that across function boundaries (i.e.: call one function in a loop, and put the `continue` in the function). Possible solution: Make the function return a boolean, and then at the place where you call the function inside the loop, check the return value and do `continue` there as appropriate. – Jesper Sep 13 '22 at 12:49

5 Answers5

2

Return a boolean from the function and based on the return value make continue or not because continue must be within a loop

1

continue keyword in python is only available in for or while loops. Also block defined variables like a are not available on the global scope.

I don't know what you want to achieve but assuming your code, you want to extract a condition into a function, something like this:

def condition(a):
    return a == 1

def sample(a):
   print(a)

for i in language:
    a=i
    if condition(a):
       sample(a)
    else:
       continue

Hrimiuc Paul
  • 108
  • 6
1

There are several best-practice patterns of exactly how to do this, depending on your needs.

0. Factor your code better

Before doing any of the below, stop and ask yourself if you can just do this instead:

def sample(a):
    print(a)


for i in language:
    if i != 1:
        continue
    sample(i)

This is so much better:

  1. it's clearer to the reader (everything you need to understand the loop's control flow is entirely local to the loop - it's right there in the loop, we don't have to look anywhere else farther away like a function definition to know when or why or how the loop will do the next thing),

  2. it's cleaner (less boilerplate code than any of the solutions below),

  3. it's more efficient, technically (not that this should matter until you measure a performance problem, but this might appeal to you; going into a function and coming back out of it, plus somehow telling the loop outside the function to continue - that's more work to achieve the same thing), and

  4. it's simpler (objectively: there is less code complected together - the loop behavior is no longer tied to the body of the sample function, for example).

But, if you must:

1. Add boolean return

The simplest change that works with your example is to return a boolean:

def sample(a):
    if a==1:
        print(a)
    else:
        return True
    return False


for i in language:
    if sample(i):
        continue

However, don't just mindlessly always use True for continue - for each function, use the one that fits with the function. In fact, in well-factored code, the boolean return value will make sense without even knowing that you are using it in some loop to continue or not.

For example, if you have a function called check_if_valid, then the boolean return value just makes sense without any loops - it tells you if the input is valid - and at the same time, either of these loops is sensible depending on context:

for thing in thing_list:
    if check_if_valid(thing):
        continue
    ...  # do something to fix the invalid things
for thing in thing_list:
    if not check_if_valid(thing):
        continue
    ...  # do something only with valid things

2. Reuse existing return

If your function already returns something, or you can rethink your code so that returns make sense, then you can ask yourself: is there a good way to decide to continue based on that return value?

For example, let's say inside your sample function you were actually trying to do something like this:

def sample(a):
    record = select_from_database(a)
    if record.status == 1:
        print(record)
    else:
        continue

Well then you can rewrite it like this:

def sample(a):
    record = select_from_database(a)
    if record.status == 1:
        print(record)
    return record


for i in language:
    record = sample(a)
    if record.status != 1:
        continue

Of course in this simple example, it's cleaner to just not have the sample function, but I am trusting that your sample function is justifiably more complex.

3. Special "continue" return

If no existing return value makes sense, or you don't want to couple the loop to the return value of your function, the next simplest pattern is to create and return a special unique "sentinel" object instance:

_continue = object()

def sample(a):
    if a==1:
        print(a)
    else:
        return _continue


for i in language:
    result = sample(i):
    if result = _continue:
        continue

(If this is part of a module's API, which is something that you are saying if you name it like sample instead of like _sample, then I would name the sentinel value continue_ rather than _continue... But I also would not make something like this part of an API unless I absolutely had to.)

(If you're using a type checker and it complains about returning an object instance conflicting with your normal return value, you can make a Continue class and return an instance of that instead of an instance of object(). Then the type hinting for the function return value can be a type union between your normal return type and the Continue type. If you have multiple control flow constructs in your code that you want to smuggle across function call lines like this.)

4. Wrap return value (and "monads")

Sometimes, if the type union thing isn't good enough for some reason, you may want to create a wrapper object, and have it store either your original return value, or indicate control flow. I only mention this option for completeness, without examples, because I think the previous options are better most of the time in Python. But if you take the time to learn about "Option types" and "maybe monads", it's kinda like that.

(Also, notice that in all of my examples, I fixed your backdoor argument passing through a global variable to be an explicit clearly passed argument. This makes the code easier to understand, predict, and verify for correctness - you might not see that yet but keep an eye out for implicit state passing making code harder to follow and keep correct as you grow as a developer, read more code by others, and deal with bugs.)

mtraceur
  • 3,254
  • 24
  • 33
0

It is because the scope of the function doesn't know we are in a loop. You have to put the continue keyword inside the loop

Jimpsoni
  • 233
  • 2
  • 13
0

continue keyword cannot be used inside a function. It must be inside the loop. There is a similar question here. Maybe you can do something like the following.


    language = [1,1,1,2,3]
    a = 1
    
    def sample():
        if a == 1:
            print(a)
            return False
        else:
            return True
    
    for i in language:
        if sample():
            continue
        else:
            a = i
    

OR something like this:


    language = [1,1,1,2,3]
    a = 1
    
    def gen(base):
        for item in base:
            if a == 1:
               yield a
            else:
                continue
    
    for i in gen(language):
        a = i
        print(a)