How to duplicate elements in a nested list?

Viewed 425

I have a nested list that looks like this:

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

I want to duplicate each element in each inner list by 3 and place them side to side as such:

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

This is my current solution:

from itertools import repeat

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

ls = []
for i in x2:
    ls.append([x for item in i for x in repeat(item, 3)])
ls
>>> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
 [5, 5, 5, 6, 6, 6, 7, 7, 7],
 [9, 9, 9, 10, 10, 10, 11, 11, 11],
 [4, 4, 4, 8, 8, 8, 3, 3, 3]]

Is there any way to make it faster?

2 Answers

Here is one solution:

ls=[sum([[i]*3 for i in k], []) for k in x2]

>>>print(ls)
[[1, 1, 1, 2, 2, 2, 3, 3, 3], [4, 4, 4, 5, 5, 5, 6, 6, 6], [7, 7, 7, 8, 8, 8, 9, 9, 9]]

As you asked for faster, here are some comparisons between the different possible ways presented here and other places.

The results (on my machine) are (ordered ascending):

using_zip         5.630
using_repeat_comp 5.818
using_sum         5.905
using_repeat      6.421
using_pure        6.878

Surprisingly (to me), the zip solution is actually fastest, and the list-comp version of your repeat solution second. I would assume that the "pure" list-comp will be fastest but it was actually the worst. I guess TIL...


There is another result (proposed by @Henry Tjhia):

using_sort        3.219

Significantly better as you can see, but I put it separately as it relies heavily on the above specific example. So if you want to duplicate a list of ascending numbers that would be your best choice.


The code to produce them is:

import timeit
from itertools import repeat

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

def using_repeat():
    ls = []
    for i in x2:
        ls.append([x for item in i for x in repeat(item, 3)])
    return ls

def using_repeat_comp():
    return [[x for item in i for x in repeat(item, 3)] for i in x2]

def using_zip():
    return [[x for triple in zip(l, l, l) for x in triple] for l in x2]

def using_sum():
    return [sum([[i]*3 for i in k], []) for k in x2]

def using_pure():
    return [[val for val in sublist for _ in range(3)] for sublist in x2]

def using_sort():
    return [sorted(sub[:]*3) for sub in x2]

for func in [using_repeat, using_repeat_comp, using_zip, using_sum, using_pure, using_sort]:
    print(func.__name__, timeit.timeit(f"{func.__name__}()", f"from __main__ import {func.__name__}"))
Related