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

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

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]

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

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

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

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)

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

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]

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

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.