Python'da bir listeyi doldurmak için bazı yerleşik


110

< N boyutunda bir listem var ve bunu N boyutuna bir değerle doldurmak istiyorum.

Elbette, aşağıdakine benzer bir şey kullanabilirim, ancak kaçırdığım bir şey olması gerektiğini hissediyorum:

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

Bunu neden yapmak istiyorsun? Muhtemelen daha iyi bir yol var.
Katriel

Listeyi, sabit sütun sayısıyla sekmeyle ayrılmış bir dizeye serileştiriyorum.
newtover

'\ T'.join ([1,' ',' ',' ',' ']) gibi bir şey yaptığınızı mı söylüyorsunuz? Belki bize hayata geçirmeyi düşündüğünüz şey hakkında daha fazla bilgi verirsiniz, sonra bir fikir bulmaya çalışabiliriz.
satoru

@ Satoru.Logic: evet, yazdır >> a_stream, '\ t'.join (the_list) uygulamak istediğim tek şey
newtover

Yanıtlar:


165
a += [''] * (N - len(a))

ya da ayerinde değiştirmek istemiyorsan

new_a = a + [''] * (N - len(a))

her zaman bir alt sınıf listesi oluşturabilir ve yöntemi istediğiniz gibi çağırabilirsiniz.

class MyList(list):
    def ljust(self, n, fillvalue=''):
        return self + [fillvalue] * (n - len(self))

a = MyList(['1'])
b = a.ljust(5, '')

3
Bu görünüm çok daha iyi, ama yine de bir gibi bir şey beklemek dolgu veya ped ) yöntemiyle ya da fonksiyon =
newtover

31

Bu yaklaşımın daha görsel ve pitonik olduğunu düşünüyorum.

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

Bunu anlamam yarım dakikamı alıyor. Kabul edilen cevap çok daha basittir.
Richard Möhn

4
@ RichardMöhn "pythonic", "deyimsel" anlamına gelir. Python'u ne kadar uzun süre kullanırsanız, bu sözdizimini o kadar doğal bulacaksınız.
Nuno André

4
Pythonic'in ne anlama geldiğini biliyorum. Ve 2014'ten beri sürekli olarak Python kullanıyorum. Hâlâ cevabınızı doğal bulmuyorum.
Richard Möhn

Bir ara atma listesi oluşturmayı pitonik yapan nedir?
DylanYoung

1
@DylanYoung bu ilk ne zaman durum böyle değil N < len(a). Sağladığınız ikinci cevap için durum böyledir.
kon psych

25

Bunun için yerleşik bir işlev yoktur. Ancak, göreviniz (veya herhangi bir şey: p) için yerleşik öğeleri oluşturabilirsiniz.

(Itertool padnoneve taketariflerden değiştirildi)

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)

Kullanım:

>>> list(pad([1,2,3], 7, ''))
[1, 2, 3, '', '', '', '']

6

gnibbler'ın cevabı daha güzel, ancak bir yerleşik gerekiyorsa şunu kullanabilirsiniz itertools.izip_longest( zip_longestPy3k'de):

itertools.izip_longest( xrange( N ), list )

Bu, ( i, list[ i ] )doldurulmuş tuplelar listesini Hiçbiri olarak döndürecektir . Tezgahtan kurtulmanız gerekiyorsa, aşağıdaki gibi bir şey yapın:

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

1
İzip_longest'i biliyordum ama sonuçta ortaya çıkan kod hoş görünmüyor =)
newtover

2
Kastettiğine inanıyorum operator.itemgetter(). Ayrıca Nonedeğerlerin de değiştirilmesi gerekiyor "".
pylang

5

Herhangi bir derleme olmadan basit bir jeneratör de kullanabilirsiniz. Ancak listeyi doldurmazdım, ancak uygulama mantığının boş bir listeyle ilgilenmesine izin verirdim.

Her neyse, yapı içermeyen yineleyici

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

'' Yerine Hiçbiri ile doldurmak istiyorsanız, map () işi yapar:

>>> 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çıkça söylemek gerekirse, a + [''] * (N-len (a)) çok daha net görünüyor. Ayrıca, listeye göre oyuncu seçimi yok. Ama yine de teşekkürler.
newtover

4

more-itertoolspaddedbu tür problemler için özel bir araç içeren bir kütüphanedir :

import more_itertools as mit

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

Alternatif olarak, more_itertoolsaynı zamanda Python uygulayan tarifleri itertools dahil padnoneve take@kennytm tarafından belirtildiği gibi, bunlar reimplemented olmak zorunda kalmamak:

list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]

Varsayılan Nonedolguyu değiştirmek isterseniz , bir liste anlama kullanın:

["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']

2

Kennytm'den çıkmak için:

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

Bu, listeyi oluşturmaya ve eklemeye bağlı herhangi bir çözümün aksine, fazladan ayırmayı önler [value] * extra_length. "Genişletme" yöntemi ilk __length_hint__olarak yineleyiciyi çağırır ve yineleyiciden ldoldurmadan önce tahsisatı bu kadar genişletir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.