У меня есть список размером <<em> N , и я хочу дополнить его размером до N со значением.
Конечно, я могу использовать что-то вроде следующего, но я чувствую, что должно быть что-то, что я пропустил:
>>> N = 5 >>> a = [1] >>> map(lambda x, y: y if x is None else x, a, ['']*N) [1, '', '', '', '']
a += [''] * (N - len(a))
или если вы не хотите менять 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, '')
Для этого нет встроенной функции. Но вы можете составить встроенные модули для вашей задачи (или чего-нибудь еще: p).
(Модифицировано по рецептам itertool padnone и take)
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, '', '', '', '']
Я думаю, что этот подход более визуален и питоничен.
a = (a + N * [''])[:N]
Ответ gnibbler лучше, но если вам нужен встроенный модуль, вы можете использовать itertools.izip_longest (zip_longest в Py3k):
itertools.izip_longest
zip_longest
itertools.izip_longest( xrange( N ), list )
, который вернет список кортежей ( i, list[ i ] ) заполненный None. Если вам нужно избавиться от счетчика, сделайте что-то вроде:
( i, list[ i ] )
map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
Если вы хотите дополнить 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)
Вы также можете использовать простой генератор без каких-либо сборок. Но я не стал бы дополнять список, но позволил бы логике приложения иметь дело с пустым списком.
Во всяком случае, итератор без 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()
more-itertools - это библиотека, которая включает специальный инструмент padded для решения этой проблемы:
more-itertools
padded
import more_itertools as mit list(mit.padded(a, "", N)) # [1, '', '', '', '']
В качестве альтернативы more_itertools также реализует Python рецепты itertools , включая padnone и take, как упомянуто @kennytm, поэтому их не нужно переопределять:
more_itertools
list(mit.take(N, mit.padnone(a))) # [1, None, None, None, None]
Если вы хотите заменить заполнение None по умолчанию, используйте понимание списка:
None
["" if i is None else i for i in mit.take(N, mit.padnone(a))] # [1, '', '', '', '']
Чтобы выйти из Кенны:
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]
extra_length = desired_length - len(l) l.extend(value for _ in range(extra_length))
Это позволяет избежать дополнительного выделения, в отличие от любого решения, которое зависит от создания и добавления списка [value] * extra_length. Метод "extended" сначала вызывает __length_hint__ для итератора и на столько увеличивает выделение для l, прежде чем заполнять его из итератора.
[value] * extra_length
__length_hint__
l