1

I have these two lists

indexes = [4, 2, 4, 6]
values = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]

I'm looking to merge these lists to be this. Each index value corresponds to the list size of the merge.

[[0, 1, 2, 3], [0, 1], [2, 3, 0, 1], [2, 3, 0, 1, 2, 3]]

The current answer I have for this is okay, but I'm wondering if there's a better method for it.

ids = []
cIndex = 0
for i in indexes:
    ids.append([values[cIndex+x] for x in xrange(i)])
    cIndex += i
chribis
  • 277
  • 7
  • 26
  • Your code produces `[[0, 1, 2, 3], [0, 1], [2, 3, 0, 1], [2, 3, 0, 1, 2, 3]]`, which is different from the list in question. What do you actually want? – vaultah Nov 22 '17 at 20:23
  • You're correct my mistake! – chribis Nov 22 '17 at 20:25
  • Very similar to other questions. See this answer in particular: https://stackoverflow.com/a/312467/560599 -- shouldn't be hard to generalize that for a list of sizes. – mghicks Nov 22 '17 at 20:33

3 Answers3

1

You may use list comprehension expression with list slicing as:

>>> indexes = [4, 2, 4, 6]
>>> values = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]

>>> [values[sum(indexes[:i]):sum(indexes[:i+1])] for i, index in enumerate(indexes)]
[[0, 1, 2, 3], [0, 1], [2, 3, 0, 1], [2, 3, 0, 1, 2, 3]]
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • This is perfect. Thank you. – chribis Nov 22 '17 at 20:25
  • 2
    @chribis : You should be careful while writing the questions and you shouldn't be changing the *basic requirement* of the question once you have the answers to it. It marks existing answers invalid answer. For example: I just got two down-votes because you changed your question :/ PS: I have updated the answer to match your desired result – Moinuddin Quadri Nov 22 '17 at 20:34
  • Quite sorry, @Moinuddin. My mistake. I've accepted your answer. – chribis Nov 22 '17 at 20:39
  • I appreciate that, but accepting the answer is not an apology. You need to be careful while initially writing the question. Ideally I should have rollback your question to previous version. But since you are new here, I think you weren't knowing about it, and will be careful in the future :) – Moinuddin Quadri Nov 22 '17 at 20:43
1

A regular for loop is a readable solution to this. There's no need for the list comprehension though, just maintain the current position in the list for slicing.

def split(idxes, vals):
    res = []
    pos = 0
    for i in idxes:
        res.append(vals[pos:pos+i])
        pos += i
    return res

Or if you particularly feel like importing itertools, though it's not really needed here, you could take the cumulative sum of the indices and then use the pairwise recipe.

from itertools import accumulate, tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

Like so

>>> [values[beg:end] for beg, end in pairwise(accumulate([0]+indexes))]
[[0, 1, 2, 3], [0, 1], [2, 3, 0, 1], [2, 3, 0, 1, 2, 3]]
miradulo
  • 28,857
  • 6
  • 80
  • 93
1
indexes = [4, 2, 4, 6]
values = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]

l=[]
l2=[]
j=0
for i in range(len(indexes)):
    k=0
    while k < indexes[i]:
        l.append(values[j])
        j+=1
        k+=1
    l2.append(l)
    l=[]

print(l2)

# [[0, 1, 2, 3], [0, 1], [2, 3, 0, 1], [2, 3, 0, 1, 2, 3]]
Van Peer
  • 2,127
  • 2
  • 25
  • 35