3 Lesser Known Python Features

Photo by Universal Eye on Unsplash

Sets

This is the most interesting part. We’ll learn about what the operators <, <=, >, >= do with set operands. It’s somewhat obvious what the == operator does with sets, but there’s interesting behavior when we venture into ordering sets. If you haven’t thought about this before, try guessing how the comparison operators work before reading further.

{'bread'} <= {'bread', 'butter'} 
# True
{'bread', 'jam'} <= {'bread', 'butter'}
# False
{'bread'} <= {'bread'}
# True
{'bread'} < {'bread', 'butter'}
# True
{'bread'} < {'bread'}
# False
{'bread', 'butter'} >= {'bread'}
# True
{'bread', 'jam'} >= {'bread', 'butter'}
# False
{'bread'} >= {'bread'}
# True
{'bread', 'butter'} > {'bread'}
# True
{'bread'} > {'bread'}
# False
{'bread'} <= {'bread', 'butter'} <= {'bread', 'butter', 'eggs'}
# True
{'bread'}.issubset({'bread', 'butter'}) and {'bread', 'butter'}.issubset({'bread', 'butter', 'eggs'})

Bonus

The humble ^ operator, which is overloaded with the symmetric difference. What does it mean? It’s the set of elements that appear in one, but not both of the left and right operands:

def symmetric_difference(a: set, b: set) -> set:    
return {elt for elt in a | b if (elt in a) ^ (elt in b)}
symmetric_difference({'bread', 'butter'}, {'bread', 'jam'})
# {'butter', 'jam'}
{'bread', 'butter'} ^ {'bread', 'jam'}
# {'butter', 'jam'}

Lists, Tuples, Strings, oh my!

Comparison operators on lists, tuples and strings work the same way. The operators <, <=, >, >= define a lexicographic order, which is a way of ordering sequences of objects based on an ordering of their elements. It’s the concept of alphabetical ordering, generalized to sequences containing any type of object with < and > operators defined. This is where things get weird!

'01' == '01'
# True
'01' < '10'
# True
'11' < '2'
# True
'2' > '10' > '1'
# True
[0, 1] == [0, 1]
# True
[0, 1] < [1, 0]
# True
[1, 1] < [2]
# True
[2] > [1, 0] > [1]
# True
(0, 1) == (0, 1)
# True
(0, 1) < (1, 0)
# True
(1, 1) < (2,)
# True
(2,) > (1, 0) > (1,)
# True

Bonus

You can even compare lists of heterogenous types:

[2, 'a'] < [2, 'b']
# True
[2, [1, 0]] < [2, [2, 1]] # (:
# True
[3, 4] < [3, 'a']
# TypeError: '<' not supported between instances of 'int' and 'str'

Conclusion

I hope this exploration got you thinking about what your programming language can and should do, as opposed to reusing snippets you’ve already seen. Next time you think of something and wonder if it works, try it out!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store