Einige sind integriert, um eine Liste in Python aufzufüllen


110

Ich habe eine Liste mit der Größe < N und möchte sie mit einem Wert auf die Größe N auffüllen.

Natürlich kann ich so etwas wie das Folgende verwenden, aber ich bin der Meinung, dass es etwas geben sollte, das ich verpasst habe:

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

Warum willst du das tun? Es gibt wahrscheinlich einen besseren Weg.
Katriel

Ich serialisiere die Liste in eine durch Tabulatoren getrennte Zeichenfolge mit der festen Anzahl von Spalten.
Newtover

Meinst du, du machst so etwas wie '\ t'.join ([1,' ',' ',' ',' '])? Vielleicht können Sie uns mehr darüber erzählen, was Sie implementieren möchten, und dann können wir versuchen, eine Idee zu entwickeln.
Satoru

@ Satoru.Logic: Ja, print >> a_stream, '\ t'.join (the_list) ist alles, was ich implementieren möchte
newtover

Antworten:


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

oder wenn Sie nicht an aOrt und Stelle ändern möchten

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

Sie können jederzeit eine Unterklasse von Listen erstellen und die Methode nach Belieben aufrufen

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

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

3
Das sieht viel besser aus, aber ich erwarte immer noch so etwas wie eine Füll- oder Pad- Methode oder -Funktion =)
Newtover

30

Ich denke, dieser Ansatz ist visueller und pythonischer.

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

Ich brauche eine halbe Minute, um zu verstehen. Die akzeptierte Antwort ist viel einfacher.
Richard Möhn

3
@ RichardMöhn "pythonic" bedeutet "idiomatisch". Je länger Sie Python verwenden, desto natürlicher wird diese Syntax.
Nuno André

4
Ich weiß, was "pythonisch" bedeutet. Und ich benutze Python seit 2014 ununterbrochen. Ich finde Ihre Antwort immer noch nicht natürlich.
Richard Möhn

Was macht es pythonisch, eine Zwischenliste zu erstellen?
DylanYoung

1
@ DylanYoung Dies ist nicht der Fall für den ersten Zeitpunkt N < len(a). Dies ist der Fall für die zweite Antwort, die Sie gegeben haben.
kon psych

25

Hierfür gibt es keine eingebaute Funktion. Sie können jedoch die integrierten Funktionen für Ihre Aufgabe erstellen (oder alles: p).

(Geändert von itertools padnoneund takeRezepten)

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)

Verwendung:

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

6

Die Antwort von gnibbler ist besser, aber wenn Sie ein eingebautes benötigen, können Sie Folgendes verwenden itertools.izip_longest( zip_longestin Py3k):

itertools.izip_longest( xrange( N ), list )

Dadurch wird eine Liste der ( i, list[ i ] )ausgefüllten Tupel an None zurückgegeben. Wenn Sie die Theke loswerden müssen, gehen Sie wie folgt vor:

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

1
Ich wusste über izip_longest Bescheid, aber der resultierende Code sieht nicht gut aus =)
newtover

2
Ich glaube du meinst operator.itemgetter(). Auch die NoneWerte mussten durch ersetzt werden "".
Pylang

5

Sie können auch einen einfachen Generator ohne Einbauten verwenden. Aber ich würde die Liste nicht auffüllen, sondern die Anwendungslogik mit einer leeren Liste umgehen lassen.

Jedenfalls Iterator ohne 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()

4

Wenn Sie mit None anstelle von '' auffüllen möchten, erledigt map () die Aufgabe:

>>> 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
Um ehrlich zu sein, ein + [''] * (N-len (a)) sieht viel klarer aus. Außerdem fehlt es an Casting zur Liste. Aber danke trotzdem.
Newtover

4

more-itertoolsist eine Bibliothek, die ein spezielles paddedTool für diese Art von Problem enthält:

import more_itertools as mit

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

Alternativ können more_itertoolsauch Python- itertools-Rezepte implementiert werden, einschließlich padnoneund takewie von @kennytm erwähnt, sodass sie nicht erneut implementiert werden müssen:

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

Wenn Sie die Standardauffüllung ersetzen möchten None, verwenden Sie ein Listenverständnis:

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

2

Kennytm verlassen:

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

Dies vermeidet jede zusätzliche Zuordnung, im Gegensatz zu jeder Lösung, die vom Erstellen und Anhängen der Liste abhängt [value] * extra_length. Die "verlängern" -Methode ruft zuerst __length_hint__den Iterator auf und erweitert die Zuordnung um ldiesen Betrag, bevor sie vom Iterator ausgefüllt wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.