Search This Blog

Friday, December 15, 2017

Jython: Comprehending list comprehensions

This time, I'd like to discuss list comprehension. This is another tool used in Python and Jython. It's a very concise way of stepping through a list or a string, and processing information. You can build list comprehensions from the very basic to a complicated expression.

In an earlier post, I demonstrated a list comprehension at work with the dir() function, in returning information.

Here is a basic list comprehendion and they are enclosed in square brackets:

[expression for variable in sequence [if test-expression]]

test-expression is optional.

Let's see it in action:

>>>[x for x in ['one', 'two', 'three']]
['one', 'two', 'three']

To make it clear in my mind, I think of the first expression as the result I want, and build a list comprehension from that. Like so:

>>> [x.upper() for x in ['one', 'two', 'three']]
['ONE', 'TWO', 'THREE']

How about this?

>>> [x.startswith('t') for x in ['one', 'two', 'thre']]
[False, True, True]

It even does boolean expressions.

>>> a = 'ABC'
>>> word = ['Apple', 'Bird', 'Cat']
>>> [(x, y) for x in a for y in word if y.startswith(x)]
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]

The above is an example of a nested list comprehension with an if test-expression. You noticed the result was list of tuples. You can put the result into a variable and print only what you need.

>>> result = [(x, y) for x in a for y in word if y.startswith(x)]
>>> result[0][1]  <<< here I indexed the tuple
'Apple'

>>> result
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]

Or this:

>>> [x for (x, y) in result]
['A', 'B', 'C']

List comprehension can process files.

>>> [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']

If you are using list comprehension in a script, and you want to show the results on the screen, just put the print before the list comprehension.

>>>print [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']

Can you make a complex list comprehension? You can, with some work.

I was working on the Java class GregorianCalendar. I wanted to see if my system could disply other languages. So, I used the getAvailableLocales() method. However, this method returned a list of objects, not strings. I wanted to search for a particular county, by searching a partial string, but coudln't as U got an error saying x was not in the list.

As a workaround, I had to convert it to a string to search and have it return the index of the list element.. So, my original loop went like this:

for x in range(len(locale)):
    t = str(locale[x])
    if t.endswith('US'):
        subloc.append(locale[x])

After 3 hours or so, I was able to build a list comprehension that worked exactly as my loop:

subloc = [locale[x[0]] for x in enumerate(map(str, locale)) if x[1].endswith('US')]

Can you see how I did it? I will discuss enumerate() another day.

Is this really the Pythonic way? Maybe not, but list comprehension, when successful does marvel at the conciseness and simplicity of this powerful language.


List comprehensions allow Python/Jython do the work for you. This minimizes development time and is a great benefit of this language.

If you would like to see the full script, email me at psykiatris@gmail.com.

Till next time. Happy coding!

No comments:

Post a Comment