frixhax
frixhax

Reputation: 1385

Map list to list of lists by index (Python)

I'm looking for an efficient way to map a list of values, say

x = [1,2,3,4,5,6,7,8,9] 

to another list, containing lists of values of the same total range, for example

z = [[1,2,3], [4,5,6], [7,8,9]]. 

What I need to know is basically the index a value from x corresponds to in z. x[0]=1 would correspond to z[0], because it falls in the first bin of z, where x[7]=8 would correspond to z[2], because it falls in the third bin.

How do I identify that index of the sublists of z for each x value? In my case, x has about 50,000 values, z has about 5,000 sublists, and I have lots of those lists, so I'm looking for a way to do that as fast as possible.

Upvotes: 1

Views: 2402

Answers (3)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250921

You can use a dict here:

>>> x = [1,2,3,4,5,6,7,8,9]
>>> z = [[1,2,3], [4,5,6], [7,8,9]]
>>> dic = {y :i for i,a in enumerate(z) for y in a}
>>> dic[7]
2
>>> dic[8]
2
>>> dic[1]
0

Upvotes: 5

MrGumble
MrGumble

Reputation: 5766

It appears you are searching in intervals and you could use an Interval Tree. A quick google shows https://github.com/tylerkahn/intervaltree-python, and with some modification, I expect it to work quite efficiently.

My modified module is found at http://pastebin.com/M6rpYt44 and simply adds a sequential attribute, key, if it does not already exist.

from IntervalTree import *

x = [1,2,3,4,5,6,7,8,9]
z = [[1,2,3], [4,5,6], [7,8,9]]

intervals = [Interval(l[0],l[-1]) for l in z]
it = IntervalTree(intervals)

# search
[it.search(i)[0].key for i in x]
# [0, 0, 0, 1, 1, 1, 2, 2, 2]

Upvotes: 0

Prasath
Prasath

Reputation: 605

>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [[1,2,3], [4,5,6], [7,8,9]]
>>> map(lambda x: [i for i in range(len(y)) if y[i].count(x) > 0], x)
[[0], [0], [0], [1], [1], [1], [2], [2], [2]]
>>> 
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [[1,2,3], [4,5,6], [7,8,9], [1,2,3]]
>>> map(lambda x: [i for i in range(len(y)) if y[i].count(x) > 0], x)
[[0, 3], [0, 3], [0, 3], [1], [1], [1], [2], [2], [2]]
>>> 
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 9, 7]]
>>> map(lambda x: [i for i in range(len(y)) if y[i].count(x) > 0], x)
[[0, 3], [0], [0], [1], [1], [1], [2, 3], [2], [2, 3]]
>>> 
>>> x = [ 4, 5, 6, 7, 8, 9, 1, 2, 3]
>>> y = [[1, 2, 3], [7, 8, 9], [1, 9, 7], [4, 5, 6]]
>>> map(lambda x: [i for i in range(len(y)) if y[i].count(x) > 0], x)
[[3], [3], [3], [1, 2], [1], [1, 2], [0, 2], [0], [0]]
>>> 

>>> x = [ 4, 5, 6, 7, 8, 9, 1, 2, 3]
>>> y = [[1, 2, 3], [7, 8, 9], [1, 9, 7], [4, 5, 6]]
>>> d = {}
>>> d.update(map(lambda x: (x, [i for i in range(len(y)) if y[i].count(x) > 0]), x))
>>> d
{1: [0, 2], 2: [0], 3: [0], 4: [3], 5: [3], 6: [3], 7: [1, 2], 8: [1], 9: [1, 2]}
>>> 

I think it works!

Upvotes: 0

Related Questions