web-dev-qa-db-fra.com

Certains intégrés pour remplir une liste dans python

J'ai une liste de taille < N et je veux la remplir jusqu'à la taille N avec une valeur.

Certes, je peux utiliser quelque chose comme ce qui suit, mais je pense qu'il devrait y avoir quelque chose que j'ai manqué:

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

ou si vous ne voulez pas changer a en place

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

vous pouvez toujours créer une sous-classe de liste et appeler la méthode comme bon vous semble

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

a = MyList(['1'])
b = a.ljust(5, '')
136
John La Rooy

Je pense que cette approche est plus visuelle et Pythonique.

a = (a + N * [''])[:N]
21
Nuno André

Il n'y a pas de fonction intégrée pour cela. Mais vous pouvez composer les éléments intégrés pour votre tâche (ou n'importe quoi: p).

(Modifié à partir des recettes padnone et take d'itertool)

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

la réponse de gnibbler est plus agréable, mais si vous avez besoin d'une fonction intégrée, vous pouvez utiliser itertools.izip_longest (Zip_longest en Py3k):

itertools.izip_longest( xrange( N ), list )

qui renverra une liste de tuples ( i, list[ i ] ) rempli à Aucun. Si vous devez vous débarrasser du comptoir, faites quelque chose comme:

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

Si vous souhaitez remplir avec None au lieu de '', map () fait le travail:

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

Vous pouvez également utiliser un générateur simple sans aucune compilation. Mais je ne remplirais pas la liste, mais laisserais la logique d'application gérer une liste vide.

Quoi qu'il en soit, itérateur sans 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 __== '__main__':
    import doctest
    doctest.testmod()
4
Thierry

more-itertools est une bibliothèque qui inclut un outil spécial padded pour ce type de problème:

import more_itertools as mit

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

Alternativement, more_itertools implémente également Python recettes itertools y compris padnone et take = comme mentionné par @kennytm, ils n'ont donc pas besoin d'être réimplémentés:

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

Si vous souhaitez remplacer le remplissage par défaut None, utilisez une compréhension de liste:

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

Pour quitter 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
aberger
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))

Cela évite toute allocation supplémentaire, contrairement à toute solution qui dépend de la création et de l'ajout de la liste [value] * extra_length. La méthode "extend" appelle d'abord __length_hint__ sur l'itérateur, et étend d'autant l'allocation pour l avant de le remplir depuis l'itérateur.

0
Paul Crowley