Why does "return s and s.strip()" work when using filter?
def not_empty(s): return s and s.strip() list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])) # result: ['A', 'B', 'C']
I don't know why this worked. I know that : x and y if x is false, then x, else y. So first is return 'A' and 'A'.strip(). But this showed in python IDLE
>>>'A' is True False >>>'A' is False False
So. not_empty('A') returned 'A', right? 'A'is not True, why is it in the result?
' ' is also False.
>>>' ' is True False >>>' ' is False False
filterfunction into a good ol'
old = ['A', '', 'B', None, 'C', ' '] new =  for i in old: if i and i.strip(): new.append(i) print(new)
['A', 'B', 'C']
Why this happens is because of the
ifwhich evaluates the truthiness of expressions.
You should know that all empty iterables (including the empty string
0.0are all evaluated to
Falsein an expression. There are some space strings, which when stripped, are reduced to the empty string which are also evaluated to
Going over each element, this is how your program runs:
Initial old = ['A', '', 'B', None, 'C', ' '] new =  Iteration 1 i = 'A' 'A' and 'A'.strip() is evaluated to True new = ['A'] Iteration 2 i = '' '' is evaluated to False (short circuit) new = ['A'] Iteration 3 (same as 1) i = 'B' ... new = ['A', 'B'] Iteration 4 i = None None is evaluated to False new = ['A', 'B'] Iteration 5 (same as 1, 3) i = 'C' ... new = ['A', 'B', 'C'] Iteration 6 i = ' ' ' ' is True but ' '.strip() is False new = ['A', 'B', 'C'] Final new = ['A', 'B', 'C']
First let's do some basic debugging.
"A" and "A".strip()prints "A" to the shell
Now why does it do that. Well let's look up how
A and Breturns
A is False, and
"A".strip()=="A", So the
filteris called, it will apply the function and check the result, and each time it will not get
False. because of this, it will accept the value into the new list.