Justin Nelligan
Justin Nelligan

Reputation: 495

Python: how to map one list and one list of list together

So I'm trying to get rid of some nested loops through map() and have trouble with a specific case.

I have two lists:

List1 = [1, 2, 3, 4, 5]

List2 = [[1, 2, 3], [5], [1, 6], [1, 0, 9, 10], [1, 5, 2]]

So basically list1 and list 2 are the same lengths, but list 2 is a list of lists of variable lengths.

I want to call some function on the equivalent of;

(1,1), (1,2), (1,3), (2,5), (3,1), (3,6), (4,1), (4,0), (4,9) (4,10), (5,1), (5,5), (5,2)

using map. The first parameter of the tuple is from List1 and the second one is from the i'th equivalent of list1 on list2, with the sublist expanded.

so right now I have:

map(function, zip(list1, list2))

but I cannot see how I could expand list2 to get what I just described. I think it might involve list comprehensions, but I'm having a little trouble and trial and error didn't get me very far.

Another question is, if the inner function in this nested loop is susceptible to get called millions of times, will map() be significantly faster than just a for loop?

Upvotes: 1

Views: 3477

Answers (3)

thefourtheye
thefourtheye

Reputation: 239453

Its simple with list comprehension, like this

list1 = [1, 2, 3, 4, 5]
list2 = [[1, 2, 3], [5], [1, 6], [1, 0, 9, 10], [1, 5, 2]]
print [(item1, s) for item1, item2 in zip(list1, list2) for s in item2]

Output

[(1, 1), (1, 2), (1, 3), (2, 5), (3, 1), (3, 6), (4, 1), (4, 0), (4, 9), (4, 10), (5, 1), (5, 5), (5, 2)]

This oneliner is just a short version of

result = []
for item1, item2 in zip(list1, list2):
    for s in item2:
        result.append((item1, s))

Upvotes: 4

sylvain.meunier
sylvain.meunier

Reputation: 1

A solution using itertools (no temporary list in memory):

from itertools import *
a = chain.from_iterable( product([i], j) for i, j in izip( List1, List2 ) )

You can transform this in a list using :

list(a)

Or just walk elements using a loop.

Upvotes: 0

Anatoly Scherbakov
Anatoly Scherbakov

Reputation: 1752

List comprehensions or lambda functions can help, but the solution will be too lengthy and unreadable. Probably a naive loop is better?

def join(list1, list2):
    for head, tail in zip(list1, list2):
        for thing in tail:
            yield (head, thing)

This is a generator. You can use it the following way:

pairs = join(list1, list2)
for pair in pairs:
    # do anything with pair

Or you want to store this right in memory instead of this incremental generator?

Upvotes: 0

Related Questions