一些内置在python中填充列表的功能


110

我有一个尺寸小于N的清单我想用一个值将其填充到大小N。

当然,我可以使用类似以下的内容,但是我觉得应该缺少一些内容:

>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']

你为什么要这样做?可能有更好的方法。
卡特里尔2010年

我将列表序列化为带有固定列数的制表符分隔的字符串。
newtover

您是说正在执行类似'\ t'.join([1,'','','','']))的事情吗?也许您可以向我们详细说明您打算实现的目标,然后我们可以尝试提出一个想法。
satoru

@ Satoru.Logic:是的,打印>> a_stream,'\ t'.join(the_list)是我要实现的
newtover 2010年

Answers:


165
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, '')

3
这看起来好多了,但我仍然希望使用填充填充方法或函数=)
newtover 2010年

30

我认为这种方法更具视觉效果和Python风格。

a = (a + N * [''])[:N]

这花了我半分钟才能理解。可接受的答案要简单得多。
理查德·莫恩(RichardMöhn)

3
@RichardMöhn“ pythonic”的意思是“惯用的”。使用Python的时间越长,您会越自然地找到此语法。
努诺·安德烈

4
我知道“ pythonic”是什么意思。自2014年以来,我一直在连续使用Python。我仍然觉得您的答案不自然。
理查德·蒙(RichardMöhn)

是什么使得构造中间的一次性列表变得pythonic?
DylanYoung

1
@DylanYoung第一次不是这样N < len(a)。您提供的第二个答案就是这种情况。
kon Psych

25

没有内置功能。但是您可以为您的任务(或任何:p)组成内置函数。

(从itertool padnonetake配方修改)

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, '', '', '', '']

6

gnibbler的答案更好,但是如果需要内置的,可以使用itertools.izip_longestzip_longest在Py3k中):

itertools.izip_longest( xrange( N ), list )

这将返回( i, list[ i ] )填充为None 的元组列表。如果您需要摆脱柜台问题,请执行以下操作:

map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )

1
我知道izip_longest,但是结果代码看起来不太好=)
newtover 2010年

2
我相信你的意思operator.itemgetter()。另外,None需要值被替换""
pylang

5

您也可以使用没有任何内置插件的简单生成器。但是我不会填充列表,而是让应用程序逻辑处理一个空列表。

无论如何,没有内置插件的迭代器

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()

4

如果要用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)

2
坦率地说,a + [''] *(N-len(a))看起来更加清晰。此外,它缺少强制列表。但是还是谢谢你。
newtover 2011年

4

more-itertools是一个包含padded针对此类问题的专用工具的库:

import more_itertools as mit

list(mit.padded(a, "", N))
# [1, '', '', '', '']

另外,more_itertools还可以实现Python itertools配方padnonetake如@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, '', '', '', '']

2

离开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]


1
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))

与依赖于创建和追加list的任何解决方案不同,这避免了任何额外的分配[value] * extra_length。“ extend”方法首先调用__length_hint__迭代器,并l在从迭代器填充之前将分配扩展了那么多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.