Некоторые встроенные, чтобы дополнить список в Python
У меня есть список размером < N, и я хочу дополнить его размером до N со значением.
Конечно, я могу использовать что-то вроде следующего, но я чувствую, что должно быть что-то, что я пропустил:
>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
14 ответов
a += [''] * (N - len(a))
или если вы не хотите менять a
на месте
new_a = a + [''] * (N - len(a))
вы всегда можете создать подкласс списка и вызывать метод по своему усмотрению
class MyList(list):
def ljust(self, n, fillvalue=''):
return self + [fillvalue] * (n - len(self))
a = MyList(['1'])
b = a.ljust(5, '')
Я думаю, что этот подход более визуален и питоничен.
a = (a + N * [''])[:N]
Для этого нет встроенной функции. Но вы можете составить встроенные модули для вашей задачи (или что-нибудь еще: p).
(Модифицировано из itertool's padnone
а также take
рецепты)
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)
Использование:
>>> list(pad([1,2,3], 7, ''))
[1, 2, 3, '', '', '', '']
more-itertools
это библиотека, которая включает в себя специальный padded
инструмент для решения этой проблемы:
import more_itertools as mit
list(mit.padded(a, "", N))
# [1, '', '', '', '']
С другой стороны, more_itertools
также реализует рецепты Python itertools, включая padnone
а также take
как упомянуто @kennytm, поэтому их не нужно переопределять:
list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]
Если вы хотите заменить по умолчанию None
padding, используйте понимание списка:
["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']
Ответ Gnibbler лучше, но если вам нужен встроенный, вы можете использовать itertools.izip_longest
(zip_longest
в Py3k):
itertools.izip_longest( xrange( N ), list )
который вернет список кортежей ( i, list[ i ] )
заполнено на None. Если вам нужно избавиться от счетчика, сделайте что-то вроде:
map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
Вы также можете использовать простой генератор без каких-либо сборок. Но я не стал бы дополнять список, но позволил бы логике приложения иметь дело с пустым списком.
Во всяком случае, итератор без build ins
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()
Использование итераторов и использование аргумента по умолчанию для next
:
i = iter(a)
a = [next(i, '') for _ in range(N)]
Краткое объяснение:
В любом случае мы хотим производить
N
Предметы. Следовательно
for _ in range(N)
. Тогда элементов должно быть как можно больше из
a
и остальное
''
. Использование итератора над
a
мы захватываем все возможные элементы, и когда мы получаем
StopIteration
, будет возвращено значение по умолчанию, которое
''
.
Если вы хотите добавить None вместо '', map() сделает свою работу:
>>> 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)
Вы можете использовать *
итеративный оператор распаковки:
N = 5
a = [1]
pad_value = ''
pad_size = N - len(a)
final_list = [*a, *[pad_value] * pad_size]
print(final_list)
выход:
[1, '', '', '', '']
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))
Это позволяет избежать дополнительного выделения ресурсов, в отличие от любого решения, которое зависит от создания и добавления списка. [value] * extra_length
, Метод "extends" сначала вызывает __length_hint__
на итераторе, и расширяет выделение для l
тем самым, прежде чем заполнять его из итератора.
Добавление отступа перед списком элементов
a[:0] += [''] * (N - len(a))
Добавление заполнения после списка элементов
a += [''] * (N - len(a))
Чтобы выйти из Кеннитм:
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]
Добавление к существующему списку с помощью
np.repeat
:
import numpy as np
a + list(np.repeat([''], (N - len(a))))
Пифонический способ заполнить ваш список пустыми элементами — использовать понимание списка.
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 )]