Ini cukup n00bish, tapi saya mencoba belajar / memahami pemrograman fungsional dengan python. Kode berikut:
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]
def maptest(foo, bar):
print foo, bar
map(maptest, foos, bars)
menghasilkan:
1.0 1
2.0 2
3.0 3
4.0 None
5.0 None
P. Apakah ada cara untuk menggunakan peta atau alat fungsional lain dalam python untuk menghasilkan yang berikut tanpa loop dll.
1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]
Hanya sebagai catatan bagaimana implementasi akan berubah jika ada ketergantungan antara foo dan bar. misalnya
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]
dan cetak:
1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...
PS: Saya tahu bagaimana melakukannya dengan naif menggunakan loop, dan / atau generator, tapi saya ingin belajar bagaimana mencapai hal yang sama dengan menggunakan alat fungsional. Apakah ini hanya kasus menambahkan pernyataan if ke maptest atau menerapkan peta filter lain ke bar secara internal di dalam maptest?
python
dictionary
functional-programming
eusoubrasileiro
sumber
sumber
Jawaban:
Cara termudah adalah tidak melewati
bars
fungsi yang berbeda, tetapi untuk mengaksesnya langsung darimaptest
:Dengan
maptest
fungsi asli Anda, Anda juga bisa menggunakan fungsi lambda dimap
:sumber
Apakah Anda terbiasa dengan bahasa fungsional lainnya? yaitu apakah Anda mencoba untuk mempelajari bagaimana python melakukan pemrograman fungsional, atau apakah Anda mencoba untuk belajar tentang pemrograman fungsional dan menggunakan python sebagai kendaraan?
Juga, apakah Anda memahami daftar?
setara langsung (*) untuk:
Bahkan, saya pikir
map()
pernah dijadwalkan untuk dihapus dari python 3.0 sebagai mubazir (itu tidak terjadi).sebagian besar setara dengan:
(ada perbedaan dalam cara menangani kasus di mana urutannya memiliki panjang yang berbeda. Seperti yang Anda lihat,
map()
mengisi Tidak ada ketika salah satu urutan habis, sedangkanzip()
berhenti ketika urutan terpendek berhenti)Jadi, untuk menjawab pertanyaan spesifik Anda, Anda mencoba menghasilkan hasilnya:
Anda bisa melakukan ini dengan menulis fungsi yang mengambil satu argumen dan mencetaknya, diikuti oleh bilah:
Atau, Anda dapat membuat daftar yang terlihat seperti ini:
dan gunakan maptest asli Anda:
Salah satu cara untuk melakukan ini adalah membangun daftar secara eksplisit sebelumnya:
Atau, Anda bisa menarik
itertools
modul.itertools
berisi banyak fungsi pintar yang membantu Anda melakukan pemrograman evaluasi gaya-malas dengan python. Dalam hal ini, kami inginitertools.repeat
, yang akan menampilkan argumennya tanpa batas saat Anda mengulanginya. Fakta terakhir ini berarti bahwa jika Anda melakukannya:Anda akan mendapatkan output tanpa akhir, karena
map()
terus berjalan selama salah satu argumen masih menghasilkan output. Namun,itertools.imap
sepertimap()
, tetapi berhenti segera setelah iterable terpendek berhenti.Semoga ini membantu :-)
(*) Agak berbeda dengan python 3.0. Di sana, map () pada dasarnya mengembalikan ekspresi generator.
sumber
itertools.imap(f, sequence1, sequence2)
benar-benar setara dengan[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]
?list(itertools.imap(f, sequence1, sequence2))
Inilah solusi yang Anda cari:
Saya akan merekomendasikan menggunakan pemahaman daftar (
[(x, bars) for x in foos]
bagian) lebih dari menggunakan peta karena menghindari overhead panggilan fungsi pada setiap iterasi (yang bisa sangat signifikan). Jika Anda hanya akan menggunakannya dalam for for loop, Anda akan mendapatkan kecepatan yang lebih baik dengan menggunakan pemahaman generator:Perbedaannya adalah bahwa pemahaman generator dimuat malas .
UPDATE Sebagai tanggapan terhadap komentar ini:
Saya kira ini adalah poin yang valid. Ada dua solusi untuk ini yang bisa saya pikirkan. Yang paling efisien mungkin adalah sesuatu seperti ini:
Karena tupel tidak dapat diubah, ini akan mencegah bar dimodifikasi dari hasil pemahaman daftar ini (atau pemahaman generator jika Anda memilih rute itu). Jika Anda benar-benar perlu memodifikasi setiap hasil, Anda dapat melakukan ini:
Namun, ini bisa sedikit mahal baik dalam hal penggunaan memori dan dalam kecepatan, jadi saya sarankan menentangnya kecuali jika Anda benar-benar perlu menambah masing-masing.
sumber
Pemrograman fungsional adalah tentang membuat kode bebas efek samping.
peta adalah abstraksi transformasi daftar fungsional. Anda menggunakannya untuk mengambil urutan sesuatu dan mengubahnya menjadi urutan sesuatu yang lain.
Anda mencoba menggunakannya sebagai iterator. Jangan lakukan itu. :)
Berikut adalah contoh bagaimana Anda dapat menggunakan peta untuk membangun daftar yang Anda inginkan. Ada beberapa solusi yang lebih pendek (saya hanya menggunakan pemahaman), tetapi ini akan membantu Anda memahami peta yang sedikit lebih baik:
Perhatikan pada titik ini, Anda hanya melakukan manipulasi data. Sekarang Anda dapat mencetaknya:
- Saya tidak yakin apa yang Anda maksud dengan 'tanpa loop.' fp bukan tentang menghindari loop (Anda tidak dapat memeriksa setiap item dalam daftar tanpa mengunjungi masing-masing). Ini tentang menghindari efek samping, sehingga lebih sedikit menulis bug.
sumber
sumber
sumber
Berikut ini ikhtisar parameter ke
map(function, *sequences)
fungsi:function
adalah nama fungsi Anda.sequences
adalah sejumlah urutan, yang biasanya daftar atau tupel.map
akan mengulanginya secara bersamaan dan memberikan nilai saat inifunction
. Itu sebabnya jumlah urutan harus sama dengan jumlah parameter untuk fungsi Anda.Kedengarannya seperti Anda mencoba untuk beralih ke beberapa
function
parameter tetapi tetap membuat yang lain konstan, dan sayangnyamap
tidak mendukungnya. Saya menemukan proposal lama untuk menambahkan fitur seperti itu ke Python, tetapi konstruksinya sangat bersih dan mapan sehingga saya ragu sesuatu seperti itu akan pernah diimplementasikan.Gunakan solusi seperti variabel global atau daftar pemahaman, seperti yang disarankan orang lain.
sumber
Apakah ini akan berhasil?
sumber
bar
menyiratkan itu menerima nilai berulang, ketika Anda benar-benar ingin seluruh daftar.Bagaimana dengan ini:
sumber