scrpy
scrpy

Reputation: 1021

Edge pad both sides of a list in Python

What is the best way to pad a Python list to a specific length by repeating the start element at the start and end element at the end?

For example, I have the following list of 5 elements:

['a', 'b', 'c', 'd', 'e']

and I want to edge pad both sides of it so it has a new length of 10, producing

# either
['a', 'a', 'a', 'b', 'c', 'd', 'e', 'e', 'e', 'e']

# or 
['a', 'a', 'a', 'a', 'b', 'c', 'd', 'e', 'e', 'e']

(When the target length minus the current length is an odd number, as in the example above, I don't mind which of the start and end elements is repeated once more than the other in order to correctly pad the list to the target length.)

There are several other related questions on SO (here, here and here, for example), but all of these concern zero padding (or similar) only one side. I am specifically asking about edge padding both sides.

Upvotes: 3

Views: 449

Answers (3)

scrpy
scrpy

Reputation: 1021

This can be done using simple list manipulations:

my_list = ['a', 'b', 'c', 'd', 'e']
target_len = 10

diff = target_len - len(my_list)
left = diff // 2  # explicit integer division
right = diff - left
result = left*[my_list[0]] + my_list + right*[my_list[-1]]

print(result)

Which outputs:

['a', 'a', 'a', 'b', 'c', 'd', 'e', 'e', 'e', 'e']

Using this method, if the target length minus the current length is an odd number, it is the end element which is repeated once more than the start element.

Upvotes: 1

f5r5e5d
f5r5e5d

Reputation: 3706

divmod gives both needed numbers at once, otherwise the same as landogardner ans

a, n = ['a', 'b', 'c', 'd', 'e'], 10

q, r = divmod(n - len(a), 2)

ap = [a[0]]*q + a + [a[-1]]*(q + r)

ap
Out[660]: ['a', 'a', 'a', 'b', 'c', 'd', 'e', 'e', 'e', 'e']

Upvotes: 2

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

I think your answer is fine, the only improvement I would make is to use itertools iterators for efficiency, if that is a consideration:

from itertools import chain, repeat

my_list = ['a', 'b', 'c', 'd', 'e']
final_len = 10

diff = final_len - len(my_list)
left = diff // 2
right = diff - left
result = list(chain(repeat(my_list[0], left), my_list, repeat(my_list[-1], right)))

Upvotes: 2

Related Questions