My absolute favorite feature of Python is lists. An elegantly dynamic data structure with a beautiful syntax. Everything from negative step indexing to their use as iterators makes Python lists, and therefore Python, the easiest solution to so many problems. One of the less obvious, but extremely powerful features of Python lists are list comprehensions.
Let’s say you needed to dynamically generate a list.
rot13 =  for c in string.ascii_letters: my_list.append(chr(ord(c) + 13))
That’s not necessarily bad, but we can do that a bit more elegantly with a list comprehension.
rot13 = [ chr((ord(c.lower()) + 13) % 26 + 97) for c in string.ascii_letters ]
A list comprehension takes the following form:
>>> [ <item_added_to_list> for <iteration_index> in <iterator> ]
It provides a short way for generating a list on the fly when that list requires some amount of logic or operations. You can also attach conditions to list comprehensions. If you want to get a list of squares you might do something like this:
squares = [ i**2 for i in range(50) ]
If you want to get the squares of only multiples of five, you might do something like this:
squares = [ i**2 for i in range(50) if i % 2 == 0 ]
As a more practical example, if you have a web application, you can use this to collect data from your data model.
users = [ (user.name, user.email) for user in users if user.isadmin() ]
List comprehensions have their limits. They can quickly become long and unruly, but when you need a certain amount of logic in generating a list, list comprehensions can give you a shorter more elegant way of doing so.