Pythonでリストにパディングするための組み込み


110

サイズ< Nのリストがあり、サイズNまで値で埋めたい。

確かに、次のようなものを使用できますが、見落としがあるはずだと感じています。

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

なぜこれをしたいのですか?おそらくもっと良い方法があります。
カトリエル2010

リストを、列数が固定されたタブ区切りの文字列にシリアル化します。
2010

'\ t'.join([1、' '、' '、' '、' '])のようなことをしているのですか?多分あなたはあなたが何を実装するつもりであるかについて私たちにもっと話すことができて、それから私たちはアイデアを思いつくように試みることができます。
satoru 2010

Satoru.Logic @:はい、印刷>> a_stream、「\ t'.join(the_list)私が実装するすべてである
newtover

回答:


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

3
これははるかに良く見えますが、私はまだフィルパッドのメソッドや関数のようなものを期待しています=)
newtover

30

このアプローチはより視覚的でpythonicだと思います。

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

これを理解するには30分かかります。受け入れられた答えははるかに簡単です。
RichardMöhn12年

3
@RichardMöhn "pythonic"は "慣用的"を意味します。Pythonを長く使用するほど、この構文が自然になります。
ヌーノ・アンドレ

4
「pythonic」の意味を知っています。そして、私は2014年から継続的にPythonを使用しています。それでも、あなたの答えは自然とはわかりません。
RichardMöhn

中間の使い捨てリストを作成するのに何がpythonicになるのですか?
DylanYoung

1
@DylanYoungこれは最初の場合には当てはまりませんN < len(a)。あなたが提供した2番目の答えの場合です。
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_longestPy3kで)使用できます:

itertools.izip_longest( xrange( N ), list )

これは( i, list[ i ] )、Noneに入力されたタプルのリストを返します。カウンターを取り除く必要がある場合は、次のようにします。

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

1
私はizip_longestについて知っていましたが、結果のコードは見栄えがしません=)
newtover

2
と思いますoperator.itemgetter()。また、None値をで置き換える必要がありました""
pylang 2017

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))はより明確に見えます。さらに、リストへのキャストが不足しています。とにかくありがとう。
2010年

4

more-itertoolspaddedこの種の問題のための特別なツールを含むライブラリです:

import more_itertools as mit

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

または、@ kennytmを含み、@ kennytmで言及さmore_itertoolsれているPython itertoolsレシピも実装しているため、再実装する必要はありません。padnonetake

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

これにより、リストの作成と追加に依存するソリューションとは異なり、余分な割り当てが回避されます[value] * extra_length。「拡張」メソッドは最初に__length_hint__イテレータを呼び出し、イテレータlから入力する前に割り当てをその分拡張します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.