1
def CardsAssignment():
      Cards+=1
      print (Cards)
      return break      

while True:
      CardsAssignment()

Yes, I know that I cannot return break. But how can I break a while loop by the def function? Or my concept is wrong?

Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
Anthony Lee
  • 59
  • 1
  • 2
  • 6

7 Answers7

10

No it cannot. Do something like:

def CardsAssignment():
  Cards+=1
  print (Cards)
  if want_to_break_while_loop:
    return False      
  else:
    return True

while True:
  if not CardsAssignment():
    break
steffen
  • 8,572
  • 11
  • 52
  • 90
5

A very Pythonic way to do it would be to use exceptions with something like the following:

class StopAssignments(Exception): pass  # Custom Exception subclass.

def CardsAssignment():
    global Cards  # Declare since it's not a local variable and is assigned.

    Cards += 1
    print(Cards)
    if time_to_quit:
        raise StopAssignments

Cards = 0
time_to_quit = False

while True:
    try:
        CardsAssignment()
    except StopAssignments:
        break

Another, less common approach would be to use a generator function which will return True indicating that it's time to quit calling next() on it:

def CardsAssignment():
    global Cards  # Declare since it's not a local variable and is assigned.

    while True:
        Cards += 1
        print(Cards)
        yield not time_to_quit

Cards = 0
time_to_quit = False
cr = CardsAssignment()  # Get generator iterator object.
next(cr)  # Prime it.

while next(cr):
    if Cards == 4:
        time_to_quit = True  # Allow one more iteration.
martineau
  • 119,623
  • 25
  • 170
  • 301
4

You could have CardsAssignment return True (to continue) or False (to stop) and then have

if not CardsAssignment():
    break

or indeed just loop

while CardsAssignment():
Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
3

If you use a for loop instead of a while, you can cause it to break early by raiseing StopIteration - this is the usual signal for a for loop to finish, and as an exception, it can be nested inside functions as deep as you need and will propagate outward until it is caught. This means you need something to iterate over - and so, you probably want to change your function into a generator:

def cards_assignment():
     cards += 1
     yield cards

for card in cards_assignment():
    print(card)

, in which case instead of doing raise StopIteration, you would just return from the generator and the loop will finish. However, note that this (as well as options having the function return a flag that you test in the loop condition) is subtly different to using break - if you use an else clause on your loop, returning from a generator will trigger it, whereas break in the loop body won't.

lvc
  • 34,233
  • 10
  • 73
  • 98
0
def CardsAssignment():
      Cards+=1
      print (Cards)
      if (break_it):
          return False      
      else:
          return True      

while CardsAssignment():
    pass
Tisho
  • 8,320
  • 6
  • 44
  • 52
0

I would be tempted to just re-factor similar to:

def somefunc():
    from random import randint
    while True:
        r = randint(1, 100)
        if r != 42:
            yield r

And then you can do things such as:

for cnt, something in enumerate(somefunc(), start=1):
    print 'Loop {} is {}'.format(cnt, something)

This allows a possible meaningful value to be returned from somefunc() instead of using it as a "do I break" flag.

This will also allow the following construct:

sf = somefunc()
for something in sf:
    if some_condition(something):
        break

# other bits of program

for something in sf: # resume...
    pass
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
-1

in 3.5, 3.6 you can

return "break"
omgimdrunk
  • 448
  • 4
  • 16