Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory efficient padding a list

Tags:

python

I have a list

a = ['a', 'b', 'c']

of given length and I want to insert a certain element 'x' after every item to get

ax = ['a', 'x', 'b', 'x', 'c', 'x']

Since the elements are of large size, I don't want to do a lot of pops or sublists.

Any ideas?

like image 989
Jan Avatar asked Dec 13 '25 23:12

Jan


2 Answers

Since the list is large, the best way is to go with a generator, like this

def interleave(my_list, filler):
    for item in my_list:
        yield item
        yield filler

print list(interleave(['a', 'b', 'c'], 'x'))
# ['a', 'x', 'b', 'x', 'c', 'x']

Or you can return a chained iterator like this

from itertools import chain, izip, repeat
def interleave(my_list, filler):
    return chain.from_iterable(izip(my_list, repeat(filler)))
  1. repeat(filler) returns an iterator which gives filler infinite number of times.

  2. izip(my_list, repeat(filler)) returns an iterator, which picks one value at a time from both my_list and repeat(filler). So, the output of list(izip(my_list, repeat(filler))) would look like this

    [('a', 'x'), ('b', 'x'), ('c', 'x')]
    
  3. Now, all we have to do is flatten the data. So, we chain the result of izip, with chain.from_iterable, which gives one value at a time from the iterables.

like image 159
thefourtheye Avatar answered Dec 15 '25 13:12

thefourtheye


Have you considered itertools izip?

izip('ABCD', 'xy') --> Ax By

izip_longest can be used with a zero length list, a fillvalue, and combined via chain.from_iterable as follows:

import itertools
list(itertools.chain.from_iterable(itertools.izip_longest('ABCD', '', fillvalue='x'))
>>> ['A', 'x', 'B', 'x', 'C', 'x', 'D', 'x']
like image 39
Aaron Avatar answered Dec 15 '25 12:12

Aaron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!