Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping two list without looping

Tags:

python

I have two lists of equal length. The first list l1 contains data.

l1 = [2, 3, 5, 7, 8, 10, ... , 23]

The second list l2 contains the category the data in l1 belongs to:

l2 = [1, 1, 2, 1, 3, 4, ... , 3]

How can I partition the first list based on the positions defined by numbers such as 1, 2, 3, 4 in the second list, using a list comprehension or lambda function. For example, 2, 3, 7 from the first list belongs to the same partition as they have corresponding values in the second list.

The number of partitions is known at the beginning.

like image 242
Santosh Linkha Avatar asked Apr 24 '16 11:04

Santosh Linkha


3 Answers

You can use a dictionary:

>>> l1 = [2, 3, 5, 7, 8, 10, 23] 
>>> l2 = [1, 1, 2, 1, 3, 4, 3]

>>> d = {}
>>> for i, j in zip(l1, l2):
...     d.setdefault(j, []).append(i)
... 
>>> 
>>> d
{1: [2, 3, 7], 2: [5], 3: [8, 23], 4: [10]}
like image 197
Mazdak Avatar answered Oct 11 '22 22:10

Mazdak


If a dict is fine, I suggest using a defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for number, category in zip(l1, l2):
...     d[category].append(number)
... 
>>> d
defaultdict(<type 'list'>, {1: [2, 3, 7], 2: [5], 3: [8, 23], 4: [10]})

Consider using itertools.izip for memory efficiency if you are using Python 2.

This is basically the same solution as Kasramvd's, but I think the defaultdict makes it a little easier to read.

like image 29
timgeb Avatar answered Oct 11 '22 21:10

timgeb


This will give a list of partitions using list comprehension :

>>> l1 = [2, 3, 5, 7, 8, 10, 23] 
>>> l2 = [1, 1, 2, 1, 3, 4, 3]
>>> [[value for i, value in enumerate(l1) if j == l2[i]] for j in set(l2)]
[[2, 3, 7], [5], [8, 23], [10]]
like image 2
cromod Avatar answered Oct 11 '22 21:10

cromod