Why does this expression evaluate to false? - python

I thought range() returns a list of numbers . why does the all() function return a false for this
all(range(100))

Your range(100) contains 0, and the boolean value of 0 is False:
In [1]: bool(0)
Out[1]: False
while for any other number it evaluates to True. The function all only returns True when all of the elements of its argument evaluate to True, see its manual (the if statement in the given example implicitly takes the boolean value of every item). See here the difference of including 0 or not:
In [2]: all(range(10)) # 0..9
Out[2]: False
In [3]: all(range(1,10)) # 1..9
Out[3]: True

Because the first number generated by range is 0.
>>>range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 0 is evaluated to false in boolean expressions
>>>bool(0)
True
# making range start at 1
>>>all(range(1, 100))
True

Related

python any() works differently , why any([1,2]) in [1,3,5] returns True but not any(['a','b']) in ['a','v','x']? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
any([1,2]) in [1,3,5]
output is True which is right but
any(['a','b']) in ['a','v','x']
gives False which is wrong ??
why this behavior in python.??
They are actually two operations:
first evaluate 'any' and then check if the result is in the other list:
any(list) --> is there any item in the list that is equivalent to True?
any([1, 2]) --> True, any non-zero integer is equivalent to True!
any(['a', 'b']) --> True, any character is equivalent to True!
Then
is the result (True) in [1, 3, 5]? --> Yes! 1 and True are actually the same!
is the result (True) in ['a','v','x']? --> No! True (or 1) is not in the list
You can resolve your problem using 'set':
set([1, 2]) & set([1, 3, 5]) --> set([1]) --> True, any non-empty set is equivalent to True!
set(['a','b']) & set(['a','v','x']) --> set(['a']) --> True, any non-empty set is equivalent to True!
As in the comments, Python makes implicit conversion to bool ('a' --> True) when using 'any' but does exact match (1 is like an internal representation for True) when using 'in'.
any(x) returns True if and only if any of the elements of x evaluate to True.
So, any([1,2]) in [1,3,5] first evaluates any([1, 2]) which is True, since 1 is 'Truthy', and then does True in [1, 3, 5].
True in [1, 3, 5] is True because in tests the equality of items with whatever is before the in. Since, in Python, True == 1, True really is in [1, 2, 3]
Therefore any([1,2]) in [1,3,5] is True!
So why is the second one False?
This is because of the difference between 'truthiness' and equivalence.
any(['a', 'b']) is also True. Since bool('a') == True, 'a' is 'truthy'. However, True != 'a', so it falls down at the second part, because 'a' and 'True' are not equivalent That is, True is not in ['a', 'v', 'b'].
The correct any usage would be:
>>> any(x in ['a','v','x'] for x in ['a', 'b'])
True
>>> any(x in ['a','v','x'] for x in ['ea', 'b'])
False
You need to check elementwise.
You're not using any() correctly.
any() takes an iterable, and if any of the values in the iterable are truthy, it returns True, otherwise it returns False.
So, in your first example:
any([1,2]) in [1,3,5]
You're calling any() on the simple iterable [1,2], and any nonzero number is truthy, so any() returns True.
True happens to have an integer value of 1, so your statement is equivalent to 1 in [1,3,5], which is true.
You actually wanted this:
any(x in [1,3,5] for x in [1,2])
This is being evaluated in 2 parts...
any(['a','b']) is True, as is any([1,2]). So you're really asking python "Is True in the following list?"
You just happen to get lucky in the first example that 1 is treated by python as equivalent to True, so as far as it's concerned, True is in 1, 2, 3
Try... any(1, 2, 3) in (3, 4) ... False. Because 1 isn't in the second list.

Test the equality of multiple arguments with Numpy

I would like to test the equality of multiple args (i.e. it should return True if all args are equal and False if at least one argument differs).
As numpy.equal can only handle two arguments, I would have tried reduce but it, obviously, fails:
reduce(np.equal, (4, 4, 4)) # return False because...
reduce(np.equal, (True, 4)) # ... is False
You can use np.unique to check if the length of unique items within your array is 1:
np.unique(array).size == 1
Or np.all() in order to check if all of the items are equal with one of your items (for example the first one):
np.all(array == array[0])
Demo:
>>> a = np.array([1, 1, 1, 1])
>>> b = np.array([1, 1, 1, 2])
>>> np.unique(a).size == 1
True
>>> np.unique(b).size == 1
False
>>> np.all(a==a[0])
True
>>> np.all(b==b[0])
False
The numpy_indexed package has a builtin function for this. Note that it also works on multidimensional arrays, ie you can use it to check if a stack of images are all identical, for instance.
import numpy_indexed as npi
npi.all_equal(array)
If your args are floating point values the equality test can produce weird results due to round off errors. In this case you should use a more robust approach, for example numpy.allclose:
In [636]: x = [2./3., .2/.3]
In [637]: x
Out[637]: [0.6666666666666666, 0.6666666666666667]
In [638]: xarr = np.array(x)
In [639]: np.unique(xarr).size == 1
Out[639]: False
In [640]: np.all(xarr == xarr[0])
Out[640]: False
In [641]: reduce(np.allclose, x)
Out[641]: True
Note: Python 3 users will need to include the sentence from functools import reduce since reduce is no longer a built-in function in Python 3.

Using "or" in a python for loop to define default sequence

I have seen somewhere this usage of a for loop:
def func(seq=None):
for i in seq or [1, 2, 3]:
print i
func([3, 4, 5]) # Will print 3, 4, 5
func() # Will print 1, 2, 3
It seems that when using or/and when using the "in" keyword it will select the first/last "usable" sequence in order to run the for loop.
I have not seen any official documentation and was wondering how it works and if it's commonly used.
In case of or (or and ) operator, when you do -
a or b
It returns a if a is not a false-like value, otherwise it returns b . None (and empty lists) are false like value.
From documentation -
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
(Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument. This is sometimes useful, e.g., if s is a string that should be replaced by a default value if it is empty, the expression s or 'foo' yields the desired value. Because not has to invent a value anyway, it does not bother to return a value of the same type as its argument, so e.g., not 'foo' yields False, not ''.)
Also, in case of for loop, in is actually part of the for loop construct, its not an operator. Documentation for for loop construct here.
Hence when you do -
for i in seq or [1, 2, 3]:
It would first evaluate -
seq or [1 , 2, 3]
And returns the seq list if its not none or empty, so that you can iterate over that. Otherwise, it would return [1, 2, 3] and you would iterate over that.
No! It's the operator priority! or before in…
Precedence, §6.15.
So seq or [1, 2, 3] is evaluated before entering the loop. And seq is None.

How do keys work in min and max?

I run through the following sequence of statements:
>>> a = range(10)
>>> min(a, key=lambda x: x < 5.3)
6
>>> max(a, key=lambda x: x < 5.3)
0
The min and max give the exact opposite of what I was expecting.
The python documentation on min and max is pretty sketchy.
Can anyone explain to me how the "key" works?
Explanation of the key argument
Key works like this:
a_list = ['apple', 'banana', 'canary', 'doll', 'elephant']
min(a_list, key=len)
returns 'doll', and
max(a_list, key=len)
returns 'elephant'
You provide it with a function, and it uses the minimum or maximum of the results of the function applied to each item to determine which item to return in the result.
Application
If your function returns a boolean, like yours, for min it'll return the first of the minimum of True or False, (which is False) which would be 6 or the first of the max (True) which would be 0.
To see this:
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> import pprint
>>> pprint.pprint(dict((i, i<5.3) for i in a))
{0: True,
1: True,
2: True,
3: True,
4: True,
5: True,
6: False,
7: False,
8: False,
9: False}
Why?
>>> min([True, False])
False
>>> max([True, False])
True
Explanation
Why is True greater than False?
>>> True == 1
True
>>> False == 0
True
>>> issubclass(bool, int)
True
It turns out that True and False are very closely related to 1 and 0. They even evaluate the same respectively.
because all values are either True or False. So the first one of each is chosen.
min([True, 1, False, 0])
will return False instead of 0 because both have the same value but False happens first
Your code uses a key function with only boolean values so, for min, the first False
happens at the number 6. So it is the chosen one.
What you probably want to do is:
min(x for x in range(10) if x < 5.3)

How does this input work with the Python 'any' function? [duplicate]

This question already has answers here:
How exactly does a generator comprehension work?
(8 answers)
Closed 7 months ago.
In the python docs page for any, the equivalent code for the any() function is given as:
def any(iterable):
for element in iterable:
if element:
return True
return False
How does this function know what element I wanna test if call it in this form?
any(x > 0 for x in list)
From the function definition, all I can see is that I'm passing an iterable object. How does the for loop know I am looking for something > 0?
If you use any(lst) you see that lst is the iterable, which is a list of some items. If it contained [0, False, '', 0.0, [], {}, None] (which all have boolean values of False) then any(lst) would be False. If lst also contained any of the following [-1, True, "X", 0.00001] (all of which evaluate to True) then any(lst) would be True.
In the code you posted, x > 0 for x in lst, this is a different kind of iterable, called a generator expression. Before generator expressions were added to Python, you would have created a list comprehension, which looks very similar, but with surrounding []'s: [x > 0 for x in lst]. From the lst containing [-1, -2, 10, -4, 20], you would get this comprehended list: [False, False, True, False, True]. This internal value would then get passed to the any function, which would return True, since there is at least one True value.
But with generator expressions, Python no longer has to create that internal list of True(s) and False(s), the values will be generated as the any function iterates through the values generated one at a time by the generator expression. And, since any short-circuits, it will stop iterating as soon as it sees the first True value. This would be especially handy if you created lst using something like lst = range(-1,int(1e9)) (or xrange if you are using Python2.x). Even though this expression will generate over a billion entries, any only has to go as far as the third entry when it gets to 1, which evaluates True for x>0, and so any can return True.
If you had created a list comprehension, Python would first have had to create the billion-element list in memory, and then pass that to any. But by using a generator expression, you can have Python's builtin functions like any and all break out early, as soon as a True or False value is seen.
>>> names = ['King', 'Queen', 'Joker']
>>> any(n in 'King and john' for n in names)
True
>>> all(n in 'King and Queen' for n in names)
False
It just reduce several line of code into one.
You don't have to write lengthy code like:
for n in names:
if n in 'King and john':
print True
else:
print False
(x > 0 for x in list) in that function call creates a generator expression eg.
>>> nums = [1, 2, -1, 9, -5]
>>> genexp = (x > 0 for x in nums)
>>> for x in genexp:
print x
True
True
False
True
False
Which any uses, and shortcircuits on encountering the first object that evaluates True
It's because the iterable is
(x > 0 for x in list)
Note that x > 0 returns either True or False and thus you have an iterable of booleans.
Simply saying, any() does this work : according to the condition even if it encounters one fulfilling value in the list, it returns true, else it returns false.
list = [2,-3,-4,5,6]
a = any(x>0 for x in lst)
print a:
True
list = [2,3,4,5,6,7]
a = any(x<0 for x in lst)
print a:
False

Categories

Resources