2010-08-09 15 views
49

Mam listę rozmiar < N i chcę go podnieść do wielkości N z wartością.Niektóre wbudowane do listy w python

Oczywiście, można użyć coś jak poniżej, ale czuję, że nie powinno być czegoś brakowało mi:

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

Dlaczego chcesz to zrobić? Prawdopodobnie jest lepszy sposób. – katrielalex

+0

Sytuuję serializację listy w łańcuchu oddzielonym tabulatorami o stałej liczbie kolumn. – newtover

+0

Czy masz na myśli, że robisz coś w stylu "\ t'.join ([1, '', '', '', ''])? Może powiesz nam więcej o tym, co zamierzasz wdrożyć, wtedy możemy spróbować wymyślić jakiś pomysł. – satoru

Odpowiedz

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

lub jeśli nie chcesz zmieniać a w miejscu

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

zawsze możesz utworzyć podklasę listy i wywołać tę metodę, niezależnie od tego, co chcesz

Odpowiedź
+1

To wygląda o wiele lepiej, ale nadal oczekuję czegoś takiego jak metoda _fill_ lub _pad_ lub funkcja =) – newtover

+0

Chcę zmienić na miejscu. Ten pierwszy jest świetny. Pójdę z tym, dziękuję. – newtover

4

gnibbler jest ładniejszy, ale jeśli potrzebujesz pomocy wbudowanego można użyć itertools.izip_longest (zip_longest w Py3k):

itertools.izip_longest(xrange(N), list) 

który zwróci listę krotek (i, list[ i ]) wypełniony na None. Jeśli chcesz pozbyć się licznika, zrób coś takiego:

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

Wiedziałem o _izip_longest_, ale wynik kodu nie wygląda ładnie =) – newtover

+0

Wierzę, że masz na myśli 'operator.itemgetter()'. Również wartości 'None' należy zastąpić' '". – pylang

14

Nie ma w tym wbudowanej funkcji. Ale możesz skomponować wbudowane do swojego zadania (lub cokolwiek: p).

(Zmodyfikowana od itertool za padnone i take receptur)

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) 

Zastosowanie:

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

Można również użyć prostego generatora bez żadnych dodatków kompilacji. Ale nie podałbym listy, ale niech logika aplikacji zajmie się pustą listą.

Przeczą iterator bez 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() 
3

Jeśli chcesz pad z Żaden zamiast '', map() spełnia swoje zadanie:

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

Mówiąc szczerze, _a + [''] * (N-len (a)) _ wygląda znacznie jaśniej. Poza tym brakuje rzucania na listę. Ale i tak dziękuję. – newtover

0

zejść z 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] 
+0

Typo? map lub pad? – Dov

+0

Typo, dzięki za połów – aberger

3

Myślę, że to podejście jest bardziej wizualne i pythonic.

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

more-itertools jest biblioteka, który zawiera specjalny padded narzędzia tego rodzaju problem:

import more_itertools as mit 

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

Alternatywnie more_itertools implementuje również Pythona itertools recipes tym padnone i take jak podaje @kennytm, więc nie trzeba ich ponownie wdrażać:

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

Jeśli chcesz zastąpić domyślny None wyściółkę użyć wyrażeń listowych:

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