Верно или неверно в if-else - PullRequest
0 голосов
/ 23 января 2020

Мне интересно, как for l oop определяет, является ли результат is_even Истинным или Ложным. Почему is_even (i) в операторе if приводит к True, но False в операторе else?


def is_even(i):
    '''input: i, a positive int; returns True if i is even, False otherwise'''
    remainder = i%2
    return remainder == 0

for i in range(50):
    if is_even(i):
        print(is_even(i))
        print(i, 'even')
    else:
        print(is_even(i))
        print(i, 'odd')

1 Ответ

0 голосов
/ 24 января 2020

Позвольте мне пройтись по всей программе с помощью отладчика Python для вас:

https://pastebin.com/ztv42umt

> <script>(2)<module>()
-> def is_even(i):
(Pdb) list
  1     
  2  -> def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) step # We're on the function definition of `is_even`, after which it becomes available.
> <script>(7)<module>()
-> for i in range(50):
(Pdb) list
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7  -> for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
(Pdb) is_even # The `for` loop is about to start. At this point, the `is_even` function can be used, as seen below:
<function is_even at 0x70d9da4e3320>
(Pdb) step # We continue into the first iteration of the `for` loop.
> <script>(8)<module>()
-> if is_even(i):
(Pdb) list
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8  ->     if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
 13             print(i, 'odd')
(Pdb) i # Below you can see the value of the variable `i`. Since we're iterating from 0 to 49 (50 times), the first value is:
0
(Pdb) step # Let's step into `is_even` and see what returns.
--Call--
> <script>(2)is_even()
-> def is_even(i):
(Pdb) list
  1     
  2  -> def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) i # This is the argument we passed in to the `is_even` function:
0
(Pdb) step # Now we take a leap forward.
> <script>(4)is_even()
-> remainder = i%2
(Pdb) list
  1     
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4  ->     remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) step # The statement does an integral division of i by 2 and takes its remainder.
> <script>(5)is_even()
-> return remainder == 0
(Pdb) list
  1     
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5  ->     return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) remainder # And as you can see, the remainder of 0 / 2 is, of course:
0
(Pdb) step # We can now return True, meaning that the number 0 is, indeed, even.
--Return--
> <script>(5)is_even()->True
-> return remainder == 0
(Pdb) step # We're going back to the for loop.
> <script>(9)<module>()
-> print(is_even(i))
(Pdb) list
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9  ->         print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
 13             print(i, 'odd')
[EOF]
(Pdb) i, is_even(i) # [EOF] just means the end of the file, don't mind it. As you can see, is_even(i) returned True so the interpreter has taken the "first" branch. The value of `i` and the result of `is_even(i)` is, at this point:
(0, True)
(Pdb) next # Let's print the result of `is_even(i)`.
True
> <script>(10)<module>()
-> print(i, 'even')
(Pdb) next # Let's confirm again that the number was, indeed, even:
0 even
> <script>(7)<module>()
-> for i in range(50):
(Pdb) list
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7  -> for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
(Pdb) step # We're now on the next iteration. Let's fetch the next number!
> <script>(8)<module>()
-> if is_even(i):
(Pdb) list
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8  ->     if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
 13             print(i, 'odd')
(Pdb) i # So far, we told the user that the number 0 is even in two different ways (which the user is probably already aware of). What's the next number we should carry our duty on? Let's take a peek at the value of `i`:
1
(Pdb) step # Since we do (pretend to) not know whether or not 1 is even or odd, we're again taking a sneak peek inside the invocation of `is_even(1)`.
--Call--
> <script>(2)is_even()
-> def is_even(i):
(Pdb) i # This is the argument we passed in to the `is_even` function:
1
(Pdb) step # Now we take a leap forward.
> <script>(4)is_even()
-> remainder = i%2
(Pdb) list
  1     
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4  ->     remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) step # The statement does an integral division of i by 2 and takes its remainder.
> <script>(5)is_even()
-> return remainder == 0
(Pdb) list
  1     
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5  ->     return remainder == 0
  6     
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
(Pdb) remainder # And as you can see, the remainder of 1 / 2 is again, of course:
1
(Pdb) step # We can now return False, meaning that the number 1 is, undoubtly, odd.
--Return--
> <script>(5)is_even()->False
-> return remainder == 0
(Pdb) step # We're going back to the for loop. This time, with the indication of the current number being odd.
> <script>(12)<module>()
-> print(is_even(i))
(Pdb) list
  7     for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12  ->         print(is_even(i))
 13             print(i, 'odd')
[EOF]
(Pdb) i, is_even(i) # As you can see, is_even(i) returned False so the interpreter has taken the "second" branch. The value of `i` and the result of `is_even(i)` is, at this point:
(1, False)
(Pdb) next # Let's print the result of `is_even(i)`.
False
> <script>(13)<module>()
-> print(i, 'odd')
(Pdb) next # Let's confirm again that the number was, indeed, odd:
1 odd
> <script>(7)<module>()
-> for i in range(50):
(Pdb) list
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7  -> for i in range(50):
  8         if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
(Pdb) None # We've already lost our patience. After all, who doesn't know what an integer being even or odd is?
(Pdb) None # We fast forward all the way to the *last* iteration of this for loop. Let's put a breakpoint at line 8 and make it trip only when i is 49.
(Pdb) break 8
Breakpoint 1 at <script>:8
(Pdb) condition 1 i == 49
New condition set for breakpoint 1.
(Pdb) continue # Let the show begin!
True
2 even
False
3 odd
True
4 even
False
5 odd
True
6 even
False
7 odd
True
8 even
False
9 odd
True
10 even
False
11 odd
True
12 even
False
13 odd
True
14 even
False
15 odd
True
16 even
False
17 odd
True
18 even
False
19 odd
True
20 even
False
21 odd
True
22 even
False
23 odd
True
24 even
False
25 odd
True
26 even
False
27 odd
True
28 even
False
29 odd
True
30 even
False
31 odd
True
32 even
False
33 odd
True
34 even
False
35 odd
True
36 even
False
37 odd
True
38 even
False
39 odd
True
40 even
False
41 odd
True
42 even
False
43 odd
True
44 even
False
45 odd
True
46 even
False
47 odd
True
48 even
> <script>(8)<module>()
-> if is_even(i):
(Pdb) list
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7     for i in range(50):
  8 B->     if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
 13             print(i, 'odd')
(Pdb) i # This is the number we're working on:
49
(Pdb) step # The final number, hooray! We're too excited to find out whether 49 is indeed odd, don't we?
--Call--
> <script>(2)is_even()
-> def is_even(i):
(Pdb) return # This time, we skip peaking through every detail of the process of determining the number is even or odd. As you can see, remainder is 1 and therefore the function returns False:
--Return--
> <script>(5)is_even()->False
-> return remainder == 0
(Pdb) step # We let the if statement decide which branch (spoiler: it's the second) we shall proceed.
> <script>(12)<module>()
-> print(is_even(i))
(Pdb) list
  7     for i in range(50):
  8 B       if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12  ->         print(is_even(i))
 13             print(i, 'odd')
[EOF]
(Pdb) next # As you can see on the [EOF], we're heading towards the end of script. At this point it should already be clear to you that the next output would be False:
False
> <script>(13)<module>()
-> print(i, 'odd')
(Pdb) next # We somehow need the confirmation to the fact above. How fragile we are?
49 odd
> <script>(7)<module>()
-> for i in range(50):
(Pdb) list
  2     def is_even(i):
  3         '''input: i, a positive int; returns True if i is even, False otherwise'''
  4         remainder = i%2
  5         return remainder == 0
  6     
  7  -> for i in range(50):
  8 B       if is_even(i):
  9             print(is_even(i))
 10             print(i, 'even')
 11         else:
 12             print(is_even(i))
(Pdb) step # "Wait, didn't you tell me that this is the END of the iteration?" you ask. Yes it is, but we've got to *check* if it indeed is the end. You're now exiting the loop:
--Return--
> <script>(7)<module>()->None
-> for i in range(50):
(Pdb) continue # Disregard the last line. Apparantly the whole script is one big giant function so we have to step some more. We do it in a batch instead.
The program finished and will be restarted
> <script>(2)<module>()
-> def is_even(i):
(Pdb) quit # Nah we don't have to do the whole thing over again, just let me out already.

как программа оценивает результаты: is_even (i) имеет 2 доступных результата. Строка if is_even (i) может иметь значение True или False, но за ней следует print ('even'). После того, как is_even (i) выдает результат, как он соотносится с True или False?

Если это True, он немедленно переходит к следующему утверждению. Если это False, он переходит к ближайшему else: (или elif <condition>:, если есть) и продолжается оттуда. Дополнительную информацию можно найти в официальной Python документации . не определяется во время компиляции; вместо этого решение принимается каждый раз, когда переводчик запускает оператор «в реальном времени». Он чередуется между True и False, как и поток выполнения. Это запрограммировано таким образом. Если вы хотите глубже погрузиться в то, как работает любое из вышеперечисленного, вам нужно погрузиться в реализацию CPython .

...