Some built-in to pad a list in python

I have a list of size < N and I want to pad it up to the size N with a value.

Certainly, I can use something like the following, but I feel that there should be something I missed:

>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

a += [''] * (N - len(a))

or if you don’t want to change a in place

new_a = a + [''] * (N - len(a))

you can always create a subclass of list and call the method whatever you please

class MyList(list):
    def ljust(self, n, fillvalue=''):
        return self + [fillvalue] * (n - len(self))

a = MyList(['1'])
b = a.ljust(5, '')

Method 2

I think this approach is more visual and pythonic.

a = (a + N * [''])[:N]

Method 3

There is no built-in function for this. But you could compose the built-ins for your task (or anything :p).

(Modified from itertool’s padnone and take recipes)

from itertools import chain, repeat, islice

def pad_infinite(iterable, padding=None):
   return chain(iterable, repeat(padding))

def pad(iterable, size, padding=None):
   return islice(pad_infinite(iterable, padding), size)

Usage:

>>> list(pad([1,2,3], 7, ''))
[1, 2, 3, '', '', '', '']

Method 4

more-itertools is a library that includes a special padded tool for this kind of problem:

import more_itertools as mit

list(mit.padded(a, "", N))
# [1, '', '', '', '']

Alternatively, more_itertools also implements Python itertools recipes including padnone and take as mentioned by @kennytm, so they don’t have to be reimplemented:

list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]

If you wish to replace the default None padding, use a list comprehension:

["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']

Method 5

gnibbler’s answer is nicer, but if you need a builtin, you could use itertools.izip_longest (zip_longest in Py3k):

itertools.izip_longest( xrange( N ), list )

which will return a list of tuples ( i, list[ i ] ) filled-in to None. If you need to get rid of the counter, do something like:

map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )

Method 6

You could also use a simple generator without any build ins.
But I would not pad the list, but let the application logic deal with an empty list.

Anyhow, iterator without buildins

def pad(iterable, padding='.', length=7):
    '''
    >>> iterable = [1,2,3]
    >>> list(pad(iterable))
    [1, 2, 3, '.', '.', '.', '.']
    '''
    for count, i in enumerate(iterable):
        yield i
    while count < length - 1:
        count += 1
        yield padding

if __name__ == '__main__':
    import doctest
    doctest.testmod()

Method 7

If you want to pad with None instead of ”, map() does the job:

>>> map(None,[1,2,3],xrange(7))

[(1, 0), (2, 1), (3, 2), (None, 3), (None, 4), (None, 5), (None, 6)]

>>> zip(*map(None,[1,2,3],xrange(7)))[0]

(1, 2, 3, None, None, None, None)

Method 8

To go off of kennytm:

def pad(l, size, padding):
    return l + [padding] * abs((len(l)-size))

>>> l = [1,2,3]
>>> pad(l, 7, 0)
[1, 2, 3, 0, 0, 0, 0]

Method 9

extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))

This avoids any extra allocation, unlike any solution that depends on creating and appending the list [value] * extra_length. The “extend” method first calls __length_hint__ on the iterator, and extends the allocation for l by that much before filling it in from the iterator.

Method 10

you can use * iterable unpacking operator:

N = 5
a = [1]

pad_value = ''
pad_size = N - len(a)

final_list = [*a, *[pad_value] * pad_size]
print(final_list)

output:

[1, '', '', '', '']

Method 11

Using iterators and taking advantage of the default argument for next:

i = iter(a)
a = [next(i, '') for _ in range(N)]

Short explanation:

Either way we want to produce N items. Hence the for _ in range(N). Then the elements should be as much as we can from a and the rest ''. Using an iterator over a we grab all possible elements, and when we get StopIteration, the default will be returned which is ''.

Method 12

Adding to the existing list with np.repeat:

import numpy as np
a + list(np.repeat([''], (N - len(a))))

Method 13

Adding the padding before the list of elements

a[:0] += [''] * (N - len(a))

Adding the padding after the list of elements

a += [''] * (N - len(a))

Method 14

A pythonic way to pad your list with empty elements is using list comprehension.

        my_list = [1,2]
        desired_len = 3
        # Ensure that the length of my list is 3 elements
        [my_list.extend(['']) for _ in range(desired_len - len(my_list))]
        [my_list.pop() for _ in range(len(my_list)-desired_len )]


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x