Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python list comprehensions; compressing a list of lists?

guys. I'm trying to find the most elegant solution to a problem and wondered if python has anything built-in for what I'm trying to do.

What I'm doing is this. I have a list, A, and I have a function f which takes an item and returns a list. I can use a list comprehension to convert everything in A like so;

[f(a) for a in A] 

But this return a list of lists;

[a1,a2,a3] => [[b11,b12],[b21,b22],[b31,b32]] 

What I really want is to get the flattened list;

[b11,b12,b21,b22,b31,b32] 

Now, other languages have it; it's traditionally called flatmap in functional programming languages, and .Net calls it SelectMany. Does python have anything similar? Is there a neat way to map a function over a list and flatten the result?

The actual problem I'm trying to solve is this; starting with a list of directories, find all the subdirectories. so;

import os dirs = ["c:\\usr", "c:\\temp"] subs = [os.listdir(d) for d in dirs] print subs 

currentliy gives me a list-of-lists, but I really want a list.

like image 346
Steve Cooper Avatar asked Jul 02 '09 22:07

Steve Cooper


People also ask

How much faster are list comprehensions?

As we can see, the for loop is slower than the list comprehension (9.9 seconds vs. 8.2 seconds). List comprehensions are faster than for loops to create lists. But, this is because we are creating a list by appending new elements to it at each iteration.

Can you nest list comprehensions?

As it turns out, you can nest list comprehensions within another list comprehension to further reduce your code and make it easier to read still. As a matter of fact, there's no limit to the number of comprehensions you can nest within each other, which makes it possible to write very complex code in a single line.

Do list comprehensions create a new list?

List comprehensions are used for creating new lists from other iterables. As list comprehensions return lists, they consist of brackets containing the expression, which is executed for each element along with the for loop to iterate over each element.


2 Answers

You can have nested iterations in a single list comprehension:

[filename for path in dirs for filename in os.listdir(path)] 

which is equivalent (at least functionally) to:

filenames = [] for path in dirs:     for filename in os.listdir(path):         filenames.append(filename) 
like image 52
Ants Aasma Avatar answered Sep 20 '22 23:09

Ants Aasma


>>> from functools import reduce >>> listOfLists = [[1, 2],[3, 4, 5], [6]] >>> reduce(list.__add__, listOfLists) [1, 2, 3, 4, 5, 6] 

I'm guessing the itertools solution is more efficient than this, but this feel very pythonic.

In Python 2 it avoids having to import a library just for the sake of a single list operation (since reduce is a built-in).

like image 32
Julian Avatar answered Sep 16 '22 23:09

Julian