LamaMo
LamaMo

Reputation: 626

return range of indices from one list to get the values from other list

I have two lists of equal size, one has the type of data (comes in succession):

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]

The second list is about the data:

data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]

from data list, I know that "xx","tr" are "vigi" and "kl","ut","ew" are "fruits" and so on.

What I need in each time divide the data into two datasets with:

data1 = data[indices for type "vigi"]
data2 = data[indices for the remaining (i.e. data for "fruits" and "nothing")]

A second time will have:

data1 = data[indices for type "fruits"]
data2 = data[indices for the remaining (i.e. data for "vigi" and "nothing")]

And so on ..

Any help with that please.

Upvotes: 2

Views: 73

Answers (4)

Sayandip Dutta
Sayandip Dutta

Reputation: 15872

Not exactly what you wanted may be, but posting this as it may be helpful if you have a more complicated requirement in future:

>>> from itertools import groupby, count
>>> index = count()
>>> database = {key: [*group] for key, group in groupby(data, lambda x:types[next(index)])}
>>> database
{'vigi': ['xx', 'tr'],
 'fruits': ['kl', 'ut', 'ew'],
 'nothing': ['uy', 'lp', 'eq', 'aq']}

References:

  1. itertools.groupby
  2. itertools.count

Upvotes: 1

alani
alani

Reputation: 13079

A variant on the single loop solution (see other answers). Relies on the fact that a boolean will become 0 or 1 when converted to int. Might be considered hacky, but included for entertainment...

data1, data2 = [], []
out = (data2, data1)
for t, d in zip(types, data):
    out[t == 'vigi'].append(d)

print(data1)
print(data2)

Upvotes: 0

Red
Red

Reputation: 27577

Here is how you can use zip():

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]
data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]

data1 = [d for d,t in zip(data,types) if t == 'vigi']
data2 = [d for d,t in zip(data,types) if t in ['fruits','nothing']]

print(data1)
print(data2)

Output:

['xx', 'tr']
['kl', 'ut', 'ew', 'uy', 'lp', 'eq', 'aq']

Another way to go about this is to use enumerate():

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]
data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]

data1 = [d for i,d in enumerate(data) if types[i] == 'vigi']
data2 = [d for i,d in enumerate(data) if types[i] in ['fruits','nothing']]

print(data1)
print(data2)

Output:

['xx', 'tr']
['kl', 'ut', 'ew', 'uy', 'lp', 'eq', 'aq']

But that iterates over the data list twice, when only one is necessary. Instead, to improve time complexity, use a for loop:

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]
data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]

data1 = []
data2 = []

for i,d in enumerate(data):
    if types[i] == 'vigi':
        data1.append(types[i])
    elif types[i] in ['fruits','nothing']:
        data2.append(types[i])

print(data1)
print(data2)

The same goes for the zip() option (see @AndrejKesely's answer for the for loop).

Upvotes: 4

Andrej Kesely
Andrej Kesely

Reputation: 195543

You can use zip() function:

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]
data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]


data1 = [d for t, d in zip(types, data) if t == 'vigi']
data2 = [d for t, d in zip(types, data) if t != 'vigi']

print(data1)
print(data2)

Prints:

['xx', 'tr']
['kl', 'ut', 'ew', 'uy', 'lp', 'eq', 'aq']

Other version (that iterates over the lists only once):

types = ["vigi","vigi","fruits","fruits","fruits","nothing","nothing","nothing","nothing"]
data = ["xx","tr","kl","ut","ew","uy","lp","eq","aq"]

data1, data2 = [], []
for t, d in zip(types, data):
    if t == 'vigi':
        data1.append(d)
    else:
        data2.append(d)

print(data1)
print(data2)

Upvotes: 5

Related Questions