What do logical operations on lists mean?

I was looking at the source of pyftpdlib and I found this:

if self.rejected_users and self.allowed_users: raise AuthorizerError("rejected_users and allowed_users options are mutually exclusive")

rejected_users and allowed_users are lists. What confuses me is how the and operator works on two lists. I would appreciate it if someone would help me.

+4
source share
5 answers

All objects in Python have a boolean value; they are either true or false in a boolean context.

Empty lists are false. This applies to all sequences and containers, including tuples, sets, dictionaries, and strings.

The numerical value of 0 is also false, so 0, 0.0, 0j are also false, like None and, of course, False :

 >>> bool([]) False >>> bool([1, 2]) True >>> bool(0) False >>> bool('') False 

Everything else is considered true in a boolean context; therefore, a list that is not empty is true, and two non-empty lists along with and also considered true.

You can make custom types look like empty containers by implementing __len__() and returning 0 , or look at a number by doing __nonzero__() * and return False when the instance should be the logical equivalent of a numeric zero.

Just remember that and and or shortcircuit; if the first expression is blocked as a result, then this value is returned, and the second expression is ignored altogether. For and this means that in the expression x and y , y ignored if x is a false value (for example, an empty list), because in this case the whole expression cannot be true. For x or y , y ignored if x is a true value.

All of these rules are covered by the Boolean reference documentation .

* In Python 3, use __bool__ instead .

+7
source

An empty list evaluates to False , and a non-empty list evaluates to True .

if list1 and list2:

is equivalent to:

if list1 is not empty and list2 is not empty :


List of fake values ​​in python :

  • None

  • False

  • zero of any number type, for example, 0 , 0L , 0.0 , 0j .

  • any empty sequence, for example '' , () , [] .

  • any empty mapping, for example {} .

  • instances of custom classes if the class defines __nonzero__() or __len__() when this method returns the integer 0 or the value bool False.

All other values ​​are considered true, so objects of many types are always true.

+4
source

If list_a empty, then list_a and list_b will be evaluated before list_a , otherwise it will be evaluated before list_b . For instance:

 >>> [1] and [2] [2] >>> [] and [2] [] 
+1
source

In addition to @Ashwini's answer, you can use the built-in bool function to verify that the given object will evaluate.

 >>> bool([]) False >>> bool([1,2,3]) True >>> bool('') False >>> bool('hello') True 
+1
source

It seems to me that this is a logical logical expression. In Python, when constructing an If statement, logical operators have an interesting logical shorthand:

 bool = True; If bool: return "Blah!" 

Same as:

 bool = True; If bool==True: return "Blah!" 

The statement If *[boolean]* is a cooler way of saying If *[boolean]* is True . In the same way, the statement If *![boolean]* is a cooler way of saying If *[boolean]* is False , because ! is a logical operator NOT .

It takes some time to go through this logic, but once you do, it makes your code much nicer.

So why do lists do this as a boolean?

Because Python does not have an explicit type declaration, each data type has a logical representation. For lists such as rejected_users and allowed_users , if the lists are empty {} 's, it returns False , and if NOT empty, it returns True . Thus, the English translation

 if self.rejected_users and self.allowed_users: 

should read:

 if self.rejected_users is NOT empty AND if self.allowed_users is NOT empty: 

Hope this helps.

0
source

Source: https://habr.com/ru/post/1502100/


All Articles