How to interleave two lists by chunks

Question:

I want to combine two lists but in a specific way. I want every 4 values to change the list I am taking values from.

Here is an example, but the dataset I am working on is much bigger:

List1 = [1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8]
List2 = [2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8]

#Expected merged list
[1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4, 1.5, 1.6, 1.7, 1.8, 2.5, 2.6, 2.7, 2.8]

Here I’m taking the first 4 from List1, then taking the next 4 from List2, and then go back to List1 etc.

This is similar to the Intertwining two lists question but instead of having:

c = [a[0], b[0], a[1], b[1], ..., a[n], b[n]]

I want

c = [a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], ..., a[n-3], a[n-2], a[n-1], a[n], b[n-3], b[n-2], b[n-1], b[n]]
Asked By: vassilis

||

Answers:

What about this:

A = [1.1, 1.1, 1.1, 1.1, 1.2, 1.2, 1.2, 1.2, 1.3, 1.3]
B = [2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.2, 2.2, 2.3, 2.3]


sep = 4
num = len(A)
iterations = int(num / sep) + 1

merged = []
for i in range(iterations):
    start = sep * i
    end = sep * (i + 1)
    merged.extend(A[start:end])
    merged.extend(B[start:end])

print(merged)

>>> '[1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 1.2, 1.2, 1.2, 1.2, 2.2, 2.2, 2.2, 2.2, 1.3, 1.3, 2.3, 2.3]'

Answered By: marcos

You can try this. You can use extend.

>>> l=[]
>>> for i in range(0,len(List1),4):
        l.extend(List1[i:i+4])
        l.extend(List2[i:i+4])
>>> l
[1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 1.2, 1.2, 1.2, 1.2, 2.2, 2.2, 2.2, 2.2]
>>> 
Answered By: Ch3steR

This code should work just about well:

    lst1 = [1.1, 1.1, 1.1, 1.1, 1.2, 1.2, 1.2, 1.2]
    lst2 = [2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.2, 2.2]

    def combine(lst1 = [], lst2 = []):
        result = []
        for i in range(0,len(lst1), 4):
            for j in range(i, i + 4):
                result.append(lst1[i]) 
            result.append(lst2.pop(0))
            result.append(lst2.pop(0))
        for item in lst2:
            result.append(item)
        return result

    print(combine(lst1, lst2)) # [1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 1.2, 1.2, 1.2, 1.2, 2.1, 2.1, 2.2, 2.2, 2.2, 2.2]

We step through the first list four times, then add all the items into our result and removing the first 2 head elements into lst2 into our result, then finally whatever is left in lst2 is also loaded into our result.

Answered By: ismaildawud96

You could simply try this:

l=[List1[0]]*4+[List2[1]]*4+[List1[-1]]*4+[List2[-1]]*4

Answered By: dema tom

In case you want to be able to handle any list lengths (not just divisible by 4, and not just where the two lists have the same size) and any number of lists

Any list lengths

This can handle any list lengths, including where the two lists have wildly different lengths:

result = []
it1, it2 = iter(List1), iter(List2)
while chunk := list(islice(it1, 4)) + list(islice(it2, 4)):
    result += chunk

Slight alternative:

result = []
it1, it2 = iter(List1), iter(List2)
while chunk := list(chain(islice(it1, 4), islice(it2, 4))):
    result += chunk

Demo:

>>> from itertools import islice
>>> List1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> List2 = ['a', 'b', 'c', 'd', 'e']
>>> k = 4

>>> result = []
>>> it1, it2 = iter(List1), iter(List2)
>>> while chunk := list(islice(it1, k)) + list(islice(it2, k)):
        result += chunk

>>> result
[1, 2, 3, 4, 'a', 'b', 'c', 'd', 5, 6, 7, 8, 'e', 9, 10, 11, 12, 13, 14]

Any number of lists (of any lengths)

result = []
iters = deque(map(iter, Lists))
while iters:
    it = iters.popleft()
    if chunk := list(islice(it, 4)):
        result += chunk
        iters.append(it)

Demo (output formatted for clarity):

>>> from itertools import islice
>>> from collections import deque
>>> Lists = [
    [1.1, 1.1, 1.1, 1.1, 1.2, 1.2, 1.2, 1.2],
    [2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.2, 2.2, 2.3],
    [3.1, 3.1, 3.1, 3.1, 3.2, 3.2, 3.2, 3.2, 3.3, 3.4]
]
>>> k = 4

>>> result = []
>>> iters = deque(map(iter, Lists))
>>> while iters:
        it = iters.popleft()
        if chunk := list(islice(it, 4)):
            result += chunk
            iters.append(it)

>>> result
[1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 3.1, 3.1, 3.1, 3.1,
 1.2, 1.2, 1.2, 1.2, 2.2, 2.2, 2.2, 2.2, 3.2, 3.2, 3.2, 3.2,
 2.3, 3.3, 3.4]
Answered By: Kelly Bundy

As my other answer, this can handle any list lengths, but this can also handle any number of lists:

def gen(i, lst):
    for j, x in enumerate(lst):
        yield j // 4, i, x

result = [x[2] for x in merge(*(gen(*e) for e in enumerate(Lists)))]

Demo:

>>> from heapq import merge
>>> Lists = [
    [1.1, 1.1, 1.1, 1.1, 1.2, 1.2, 1.2, 1.2],
    [2.1, 2.1, 2.1, 2.1, 2.2, 2.2, 2.2, 2.2],
    [3.1, 3.1, 3.1, 3.1, 3.2, 3.2, 3.2, 3.2]
]
>>> def gen(i, lst):
        for j, x in enumerate(lst):
            yield j // 4, i, x

>>> [x[2] for x in merge(*(gen(*e) for e in enumerate(Lists)))]
[1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 3.1, 3.1, 3.1, 3.1,
 1.2, 1.2, 1.2, 1.2, 2.2, 2.2, 2.2, 2.2, 3.2, 3.2, 3.2, 3.2]
Answered By: Kelly Bundy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.