问题:一些内置在python中填充列表的功能
我有一个尺寸小于N的清单我想用一个值将其填充到大小N。
当然,我可以使用类似以下的内容,但是我觉得应该缺少一些内容:
>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
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, '', '', '', '']
回答 0
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, '')
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, '')
回答 1
我认为这种方法更具视觉效果和Python风格。
a = (a + N * [''])[:N]
I think this approach is more visual and pythonic.
a = (a + N * [''])[:N]
回答 2
没有内置功能。但是您可以为您的任务(或任何: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, '', '', '', '']
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, '', '', '', '']
回答 3
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 ) )
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 ) )
回答 4
您也可以使用没有任何内置插件的简单生成器。但是我不会填充列表,而是让应用程序逻辑处理一个空列表。
无论如何,没有内置插件的迭代器
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()
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()
回答 5
如果要用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)
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)
回答 6
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
填充,请使用列表理解:
["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']
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, '', '', '', '']
回答 7
离开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]
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]
回答 8
您可以使用*
可迭代的拆包运算符:
N = 5
a = [1]
pad_value = ''
pad_size = N - len(a)
final_list = [*a, *[pad_value] * pad_size]
print(final_list)
输出:
[1, '', '', '', '']
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, '', '', '', '']
回答 9
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))
与依赖于创建和追加list的任何解决方案不同,这避免了任何额外的分配[value] * extra_length
。“ extend”方法首先调用__length_hint__
迭代器,并l
在从迭代器填充之前将分配扩展了那么多。
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.