Beberapa built-in untuk membuat daftar dengan python

110

Saya memiliki daftar ukuran < N dan saya ingin menambahkannya ke ukuran N dengan sebuah nilai.

Tentu saja, saya dapat menggunakan sesuatu seperti berikut ini, tetapi saya merasa ada sesuatu yang saya lewatkan:

>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
newtover
sumber
Mengapa Anda ingin melakukan ini? Mungkin ada cara yang lebih baik.
Katriel
Saya membuat daftar menjadi string yang dipisahkan tab dengan jumlah kolom tetap.
newtover
Apakah maksud Anda Anda melakukan sesuatu seperti '\ t'.join ([1,' ',' ',' ',' '])? Mungkin Anda dapat memberi tahu kami lebih banyak tentang apa yang ingin Anda terapkan, kemudian kami dapat mencoba memberikan ide.
satoru
@ Satoru.Logic: yes, print >> a_stream, '\ t'.join (the_list) adalah semua yang ingin saya terapkan
newtover

Jawaban:

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

atau jika Anda tidak ingin mengubah atempatnya

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

Anda selalu dapat membuat subkelas daftar dan memanggil metode ini sesuka Anda

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

a = MyList(['1'])
b = a.ljust(5, '')
John La Rooy
sumber
3
Ini terlihat jauh lebih baik, tapi saya masih mengharapkan sesuatu seperti fill or pad method atau function =)
newtover
30

Menurut saya pendekatan ini lebih visual dan pythonic.

a = (a + N * [''])[:N]
Nuno André
sumber
Ini membutuhkan waktu setengah menit untuk saya mengerti. Jawaban yang diterima jauh lebih mudah.
Richard Möhn
3
@ RichardMöhn "pythonic" berarti "idiomatik". Semakin lama Anda menggunakan Python, semakin natural Anda akan menemukan sintaks ini.
Nuno André
4
Saya tahu apa artinya 'pythonic'. Dan saya telah menggunakan Python secara terus menerus sejak 2014. Saya masih belum menemukan jawaban Anda alami.
Richard Möhn
Apa yang membuatnya pythonic untuk membuat daftar pembuangan menengah?
DylanYoung
1
@DylanYoung ini bukan kasus pertama ketika N < len(a). Ini adalah kasus untuk jawaban kedua yang Anda berikan.
kon psych
25

Tidak ada fungsi bawaan untuk ini. Tapi Anda bisa membuat built-in untuk tugas Anda (atau apapun: p).

(Dimodifikasi dari itertool padnonedan takeresep)

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)

Pemakaian:

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

Jawaban gnibbler lebih bagus, tetapi jika Anda membutuhkan builtin, Anda dapat menggunakan itertools.izip_longest( zip_longestdi Py3k):

itertools.izip_longest( xrange( N ), list )

yang akan mengembalikan daftar tupel yang ( i, list[ i ] )diisi ke None. Jika Anda perlu menyingkirkan penghitung, lakukan sesuatu seperti:

map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
Katriel
sumber
1
Saya tahu tentang izip_longest tetapi kodenya tidak terlihat bagus =)
newtover
2
Saya percaya maksud Anda operator.itemgetter(). Juga Nonenilai - nilai yang perlu diganti "".
pylang
5

Anda juga dapat menggunakan generator sederhana tanpa build in apa pun. Tetapi saya tidak akan mengisi daftar, tetapi membiarkan logika aplikasi menangani daftar kosong.

Bagaimanapun, iterator tanpa 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()
Thierry
sumber
4

Jika Anda ingin pad dengan Tidak Ada dan bukan '', map () melakukan pekerjaan:

>>> 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)
Federico
sumber
2
Terus terang, a + [''] * (N-len (a)) terlihat jauh lebih jelas. Selain itu, tidak ada casting ke daftar. Tapi terima kasih.
newtover
4

more-itertoolsadalah pustaka yang menyertakan paddedalat khusus untuk jenis masalah ini:

import more_itertools as mit

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

Sebagai alternatif, more_itertoolsterapkan juga resep itertools Python termasuk padnonedan takeseperti yang disebutkan oleh @kennytm, sehingga tidak harus diterapkan ulang:

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

Jika Anda ingin mengganti Nonepadding default , gunakan pemahaman daftar:

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

Untuk keluar dari 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]
aberger
sumber
2

Anda dapat menggunakan * operator unpacking yang dapat diulang :

N = 5
a = [1]

pad_value = ''
pad_size = N - len(a)

final_list = [*a, *[pad_value] * pad_size]
print(final_list)

keluaran:

[1, '', '', '', '']
kederrac
sumber
1
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))

Ini menghindari alokasi tambahan, tidak seperti solusi apa pun yang bergantung pada pembuatan dan penambahan daftar [value] * extra_length. Pertama-tama, metode "perluasan" memanggil __length_hint__iterator, dan memperluas alokasi lsebanyak itu sebelum mengisinya dari iterator.

Paul Crowley
sumber