我有一个大小小于N的列表,我想用一个值填充它到大小N。
当然,我可以使用类似以下的方法,但我感觉应该有我错过的东西:
>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
我有一个大小小于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
new_a = a + [''] * (N - len(a))
你可以随时创建一个list的子类,并将方法命名为任何你想要的名称。
class MyList(list):
def ljust(self, n, fillvalue=''):
return self + [fillvalue] * (n - len(self))
a = MyList(['1'])
b = a.ljust(5, '')
我认为这种方法更加直观且符合Python风格。
a = (a + N * [''])[:N]
这方面没有内置函数可用。但是你可以组合已有的函数来完成你的任务(或者任何任务 :p)。
(修改自itertool中的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, '', '', '', '']
chain(iterable, repeat(padding))
- RoyMmore-itertools
是一个库,其中包含一个专门用于此类问题的特殊工具padded
。
import more_itertools as mit
list(mit.padded(a, "", N))
# [1, '', '', '', '']
或者,more_itertools
还实现了 Python 的 itertools recipes,包括 padnone
和 take
,正如 @kennytm 提到的那样,所以不必重新实现它们:
list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]
如果您希望替换默认的 None
填充,可以使用列表推导式:
["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']
mit.take(N, mit.padnone(a))
本身返回一个列表。 - PlaceReporter99gnibbler的答案更好,但如果你需要一个内置的函数,你可以使用itertools.izip_longest
(在Py3k中为zip_longest
):
itertools.izip_longest( xrange( N ), list )
这段代码将返回一个元组列表(i, list[i])
,其中所有值都是None。如果你需要去掉计数器,可以进行如下操作:
map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
operator.itemgetter()
。另外,None
值需要替换为 ""
。 - pylang>>> 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)
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
时,将返回默认值,即''
。
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))
这样做可以避免额外分配内存,与任何依赖于创建和附加列表 [value] * extra_length
的解决方案不同。 "extend" 方法首先在迭代器上调用 __length_hint__
,然后扩展 l
的分配大小,并从迭代器中填充它。
a.extend((N-len(a))*[padding_value])
(我使用OP符号)。 - mmj您可以使用*
可迭代解包操作符:
N = 5
a = [1]
pad_value = ''
pad_size = N - len(a)
final_list = [*a, *[pad_value] * pad_size]
print(final_list)
输出:
[1, '', '', '', '']