0

I am trying to divide a list of elements which are comma separated into chunks of unequal length. How can I divide it?

list1 = [1, 2, 1]
list2 = ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"]

list1 contains the elements which are the sizes of chunks which I wish to divide the list2 in.

Selcuk
  • 57,004
  • 12
  • 102
  • 110
Mickstjohn09
  • 103
  • 2
  • 2
  • 10
  • 2
    What is the expected result? – Selcuk Mar 18 '16 at 04:29
  • Possible duplicate of [How do you split a list into evenly sized chunks in Python?](http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python) – Dark Matter Mar 18 '16 at 05:08

5 Answers5

4

You could combine the power of itertools.accumulate and list comprehensions:

In [4]: from itertools import accumulate

In [5]: data = ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"]

In [6]: lengths = [1, 2, 1]

In [7]: [data[end - length:end] for length, end in zip(lengths, accumulate(lengths))]
Out[7]: [['1.1.1.1'], ['1.1.1.2', '1.1.1.3'], ['1.1.1.4']]

itertools.accumulate returns an iterator to a sequence of accumulated sums. This way you could easily calculate the end of each chunk in the source array:

In [8]: list(accumulate(lengths))
Out[8]: [1, 3, 4]
awesoon
  • 32,469
  • 11
  • 74
  • 99
1

Yet another solution

list1 = [1,2,1]
list2 = ["1.1.1.1","1.1.1.2","1.1.1.3","1.1.1.4"]

chunks = []
count = 0
for size in list1:
    chunks.append([list2[i+count] for i in range(size)])
    count += size
print(chunks)

# [['1.1.1.1'], ['1.1.1.2', '1.1.1.3'], ['1.1.1.4']]
pixis
  • 2,761
  • 1
  • 11
  • 26
1

You can use itertools.islice for this too. It's efficient and easy to read:

def unequal_divide(iterable, chunks):
    it = iter(iterable)
    return [list(islice(it, c)) for c in chunks]

Then to use it:

>>> list1 = [1, 2, 1]
>>> list2 = ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"]
>>> unequal_divide(list1, list2)
[['1.1.1.1'], ['1.1.1.2', '1.1.1.3'], ['1.1.1.4']]

Or as a generator:

def unequal_divide(iterable, chunks):
    it = iter(iterable)
    for c in chunks:
        yield list(islice(it, c))

In use:

>>> list(unequal_divide(list1, list2))
[['1.1.1.1'], ['1.1.1.2', '1.1.1.3'], ['1.1.1.4']]

This is also implemented in more-itertools.split_at. See here for their source code which is almost identical minus allowing no chunks to be provided which is weird.

Jab
  • 26,853
  • 21
  • 75
  • 114
1

You can also use the .pop() method like this:

list1 = [1, 2, 1]
list2 = ["1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"]

new_list = []
for chunk in list1:
    new_list.append( [ list2.pop(0) for _ in range(chunk)] )
print(new_list)


# [['1.1.1.1'], ['1.1.1.2', '1.1.1.3'], ['1.1.1.4']]

This will modify the original list2.

Jan Černý
  • 1,268
  • 2
  • 17
  • 31
Indrit
  • 35
  • 7
0

Something like:

def divideUnequal(list1, list2):
    counter=0
    step=0
    divided=[]
    for count in list1:
            step= counter+ count
            sublist= list2[counter: step]
            counter= step
            divided.append(sublist)
    return divided
Himanshu
  • 1,002
  • 9
  • 22