Reorganizing data with list & dict comprehensions
While writing scripts, I frequently run into the issue of needing to re-arrange sets of data into a more "process friendly" format. A common issue I encounter is needing to turn a list (array) into a dictionary (associative array) or vice versa. More often than not, I find myself needing to be able to access list elements by a key, but since they aren't setup in a dictionary I have to pull out a looping technique to reorganize the data for this to be possible.
Take the following set of data for example:
[[1, 'John Smith', 'admin'],
[2, 'Jane Doe', 'superuser'],
[3, 'Sam Jones', 'user']]
What we have here is a few rows of user data. In this example, the data is in a Python list (which in PHP would be an array).
In PHP, this would look something like (using print_r):
Array (
[0] => Array (
[0] => 1
[1] => John Smith
[2] => admin
)
[1] => Array (
[0] => 2
[1] => Jane Doe
# (...etc...)
So, what if I found myself writing some code that needed to be able to access each record by its first value, which in this case would be the user_id?
Well, in PHP the easiest way to make this happen would be a good-old-fashioned foreach loop:
foreach ($row as $val) {
$out[$val[0]] = $val;
}
Not very "sexy" for something I find myself having to more often than I would like, but it works nonetheless.
Now, here's where the beauty of Python kicks in. Python has a built-in feature called "comprehension" which allows you to modify and/or convert sets of data quickly and easily.
Remember what our original data set looks like? Here's a refresher:
>>> print row
[[1, 'John Smith', 'admin'],
[2, 'Jane Doe', 'superuser'],
[3, 'Sam Jones', 'user']]
Now, in Python all we need to do is use the dictionary comprehension:
>>> out = {val[0]: val for val in row} # Python 3.X
# (or, for Python 2.X)
>>> out = dict((val[0], val) for val in row) # Python 2.4+
>>> print out
{1: [1, 'John Smith', 'admin'],
2: [2, 'Jane Doe', 'superuser'],
3: [3, 'Sam Jones', 'user']}
See how easy that was?
And what if I had a dictionary in the above format, and needed to turn it into the type of list I had previously? Well, I could simply use the list comprehension to re-generate this set of data as a list:
>>> print [val for val in out.values()]
[[1, 'John Smith', 'admin'],
[2, 'Jane Doe', 'superuser'],
[3, 'Sam Jones', 'user']]
This is an extremely simple comprehension example. For a deeper look, check out Wikipedia's Python syntax page or the official Python documentation.
more...