Few days ago I was talking with my friend about most useful Python features we use almost every day. It was not about any sophisticated tools or libraries, but about the things we use often and which are “given” by the language and its syntax itself – the ones which we like just because they’re “pythonic”. I’ve picked and some of them, which are easy to describe in short devblog article. Even if most of these things should be known for most of the Python developers, I bet that many of you don’t know about at least one of them or just use to forget about using it ;)
- Variable assignment with if-else
- List Comprehension
- The for-else statement
- Data multiplication
- Sense of humor
Python is widely know as a language which is very “natural” – its syntax is clear and readable but this simplicity can be easily broken by developer. Let’s say we want to assign a value to a variable. It should be 0 if the string is shorter than 3 characters or its length if it’s greater than this.
1 2 3 4
if len(s) > 3: x = len(s) else: x = 0
OK, it works. But how about this?
x = len(s) if len(s) > 3 else 0
That’s it! Clear, much shorter, very readable and “natural”.
List comprehension is one of the most famous Python features and I guess you heard about them before, but to be absolutely sure that you are not going to miss them somehow, I decided to put them here. Let’s start from some basic example:
Let’s say that you have a list of strings (variable called list_of_words) and you want to make another list of capitalized strings from the first list, which are longer than 5 characters, but you don’t know about list comprehensions. You’ll probably write something like this:
1 2 3 4 5
cap_w = list() for s in list_of_words: if len(s) > 5: cap_w.append(s.capitalize())
OK, not bad. But how about this code?
cap_w = [s.capitalize() for s in list_of_words if len(s) > 5]
So, in general, how does it work? The basic idea is:
output_list = [element for item in input_list if condition]
The outer brackets mean that we’re going to get a list as an output. Inside we iterate (for-in) through whole list – there’s nothing special in it. The great things are “element” and “condition”.
Just before for-loop we can place any expression that operates on every selected item – we can leave it without any change, we can capitalize it if it’s a string, we can calculate it’s factorial if it’s number or we can just pass it to a function we wrote to make some more advanced things with it. We can even pass it to some class constructor to get a list of objects. Do whatever you need.
It’s not all – after the for-loop we can place condition under which we want item from the list to be used in further computation. You can use any valid expression which can be interpreted as a True or False (so – for example – numbers are OK too).
Homework – change square brackets (the outermost ones) to round brackets and check what happens then.
One very important thing about list comprehension: in most cases using them is – in terms of performance and (obviously) readability – better choice than using map(), filter() and reduce() functions. I mention about it, because some people think that fancy syntax like this always has to be slower than functions, just because it’s fancy. No, it’s not. You can read a lot about it here. Keep that in mind.
How often you set a flag before for-loop, check a condition in the loop and – if it’s satisfied – break the loop, check the flag and set some output? I do. That’s why I like the for-else statement so much. Let’s take a look at the example – checking if a list (words) contains a word of specific length. At first – with for-loop and flag:
1 2 3 4 5 6 7 8 9 10
found = False for w in words: if len(w) == 7: found = True print "Gotcha!" break if not found: print "Nope!"
and with the for-else statement:
1 2 3 4 5 6
for w in words: if len(w) == 7: print "Gotcha!" break else: print "Nope!"
How does it work? Else clause is called when we run out of items in for-loop – when it’s empty (or – was empty from the beginning). It is omitted when we leave the loop with break or when an exception is thrown. Simple, clear and useful.
Another basic, but very useful feature – it was one of the first things I’ve learned about Python, but I still meet people who are surprised that it’s possible. You can multiply some of Python’s non-numeric types – i.e. strings, lists and tuples – by any number to get them multiplied in the output.
1 2 3 4 5 6 7 8
In : ['a', 'b', 'c'] * 2 Out: ['a', 'b', 'c', 'a', 'b', 'c'] In : (1, 2, 3) * 2 Out: (1, 2, 3, 1, 2, 3) In : 'abc' * 2 Out: 'abcabc'
This one is OK too:
In : ['a', 'b', [0, 1, 2]] * 2 Out: ['a', 'b', [0, 1, 2], 'a', 'b', [0, 1, 2]]
In : import antigravity
In : import this
Don’t be too serious.
P.S. Yes, I love IPython.