Saya mencoba memetakan daftar ke hex, dan kemudian menggunakan daftar di tempat lain. Dalam python 2.6, ini mudah:
A: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
Namun, dalam Python 3.1, di atas mengembalikan objek peta.
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Bagaimana cara mengambil daftar yang dipetakan (seperti pada A di atas) di Python 3.x?
Atau, apakah ada cara yang lebih baik untuk melakukan ini? Objek daftar awal saya memiliki sekitar 45 item dan id ingin mengubahnya menjadi hex.
python
list
python-3.x
map-function
mozami
sumber
sumber
map()
itu hampir dihapus dari bahasa karena tidak ada alasan untuk menggunakannya lebih dari satu daftar pemahaman ataufor
lingkaran.Jawaban:
Melakukan hal ini:
Dalam Python 3+, banyak proses yang beralih dari iterables mengembalikan iterator sendiri. Dalam kebanyakan kasus, ini akhirnya menghemat memori, dan harus membuat segalanya berjalan lebih cepat.
Jika semua yang akan Anda lakukan adalah beralih pada daftar ini pada akhirnya, Anda tidak perlu mengubahnya menjadi daftar, karena Anda masih dapat beralih ke
map
objek seperti:sumber
map
akan menjadi evaluasi malas ketika iterasi pada fungsi yang kompleks, set data yang besar, atau stream.bytes(sequence_of_ints_in_range_0_to_256).decode('latin-1')
yang membuatstr
lebih cepat dengan menghindari panggilan fungsi Python untuk setiap elemen yang mendukung konversi massal dari semua elemen hanya menggunakan panggilan fungsi level C. Anda dapat membungkus di ataslist
jika Anda benar-benar membutuhkanlist
karakter individu, tetapi karenastr
sudah dapat diubah karakternya sendiri, satu-satunya alasan Anda akan melakukannya adalah jika Anda membutuhkan kemampuan berubah-ubah.Baru dan rapi dalam Python 3.5:
Berkat Generalisasi Pembongkaran Tambahan
MEMPERBARUI
Selalu mencari cara yang lebih pendek, saya menemukan ini juga berfungsi:
Membongkar karya di tuple juga. Perhatikan koma di bagian akhir. Ini membuatnya menjadi tupel dari 1 elemen. Artinya, ini setara dengan
(*map(chr, [66, 53, 0, 94]),)
Ini lebih pendek dengan hanya satu karakter dari versi dengan tanda kurung, tetapi, menurut pendapat saya, lebih baik untuk menulis, karena Anda mulai dengan asterisk - sintaksis ekspansi, jadi saya merasa lebih lembut di pikiran. :)
sumber
list()
tidak terlihat rapilist
konstruktor dan memanggil mesin panggilan fungsi umum. Untuk input panjang, itu tidak masalah; untuk yang singkat, itu bisa membuat perbedaan besar. Menggunakan kode di atas dengan input sebagaituple
sehingga tidak berulang kali direkonstruksi,ipython
microbenchmark menunjukkanlist()
pendekatan pembungkus membutuhkan sekitar 20% lebih lama daripada membongkar. Pikiran Anda, secara absolut, kita berbicara tentang 150 ns, yang sepele, tetapi Anda mendapatkan idenya.map
? Mungkin dengan nama baru (lmap
?) Jika default baru adalah mengembalikan iterator?*map()
memberikan kesalahan sintaks padaPython 3.6
:can't use starred expression here
. Anda harus memasukkannya ke dalamlist
:[ *map() ]
Mengapa Anda tidak melakukan ini:
Ini disebut pemahaman daftar. Anda dapat menemukan banyak informasi di Google, tetapi di sini ada tautan ke dokumentasi Python (2.6) tentang daftar pemahaman . Anda mungkin lebih tertarik pada dokumentasi Python 3 .
sumber
map(chr, [66,53,0,94])
jelas lebih ringkas daripada[chr(x) for x in [66,53,0,94]]
.Fungsi peta daftar-kembali memiliki keuntungan menghemat pengetikan, terutama selama sesi interaktif. Anda dapat mendefinisikan
lmap
fungsi (pada analogi python2'simap
) yang mengembalikan daftar:Maka menelepon
lmap
bukannyamap
akan melakukan pekerjaan:lmap(str, x)
lebih pendek dengan 5 karakter (30% dalam kasus ini) daripadalist(map(str, x))
dan tentu saja lebih pendek dari[str(v) for v in x]
. Anda juga dapat membuat fungsi serupafilter
.Ada komentar untuk pertanyaan asli:
Hal ini mungkin untuk melakukan itu, tapi itu adalah ide yang sangat buruk. Hanya untuk bersenang-senang, inilah cara Anda ( tetapi tidak seharusnya ) melakukannya:
sumber
Mengonversi komentar lama saya untuk visibilitas yang lebih baik: Untuk "cara yang lebih baik untuk melakukan ini" tanpa
map
sepenuhnya, jika input Anda dikenal sebagai ordinal ASCII, umumnya jauh lebih cepat untuk mengonversibytes
dan mendekodekan, alabytes(list_of_ordinals).decode('ascii')
. Itu memberi Andastr
nilai-nilai, tetapi jika Anda membutuhkan kemampuanlist
berubah-ubah atau sejenisnya, Anda bisa mengubahnya (dan itu masih lebih cepat). Misalnya, dalamipython
microbenchmarks, mengubah 45 input:Jika Anda membiarkannya sebagai
str
, dibutuhkan ~ 20% dari waktumap
solusi tercepat ; bahkan mengubah kembali ke daftar itu masih kurang dari 40% darimap
solusi tercepat . Konversi massal melaluibytes
danbytes.decode
kemudian konversi massal untuklist
menyimpan banyak pekerjaan, tetapi seperti disebutkan, hanya berfungsi jika semua input Anda adalah ASCII ordinals (atau ordinals dalam beberapa byte per karakter pengkodean spesifik lokal karakter, misalnyalatin-1
).sumber
berarti akan mengembalikan iterator.
berarti bahwa () fungsi iterator berikutnya akan mengambil satu nilai dari setiap iterables dan meneruskannya masing-masing ke satu parameter posisi fungsi.
Jadi Anda mendapatkan iterator dari map () funtion dan hanya meneruskannya ke list () fungsi builtin atau menggunakan pemahaman daftar.
sumber
Selain jawaban di atas
Python 3
, kami dapat dengan mudah membuatlist
nilai hasil dari amap
sebagaiKita dapat menggeneralisasi dengan contoh lain di mana saya dikejutkan, operasi pada peta juga dapat ditangani dengan cara yang sama seperti dalam
regex
masalah, kita dapat menulis fungsi untuk mendapatkanlist
item untuk dipetakan dan mendapatkan hasil yang ditetapkan pada waktu yang sama. Ex.sumber
Anda dapat mencoba mendapatkan daftar dari objek peta dengan hanya mengulangi setiap item dalam objek dan menyimpannya dalam variabel yang berbeda.
sumber
Menggunakan pemahaman daftar dalam python dan utilitas fungsi peta dasar, orang dapat melakukan ini juga:
chi = [x for x in map(chr,[66,53,0,94])]
sumber