Panggil fungsi int () pada setiap elemen daftar?

184

Saya punya daftar dengan string numerik, seperti:

numbers = ['1', '5', '10', '8'];

Saya ingin mengonversi setiap elemen daftar menjadi bilangan bulat, jadi akan terlihat seperti ini:

numbers = [1, 5, 10, 8];

Saya bisa melakukannya menggunakan loop, seperti:

new_numbers = [];
for n in numbers:
    new_numbers.append(int(n));
numbers = new_numbers;

Apakah itu harus begitu jelek? Saya yakin ada cara yang lebih pythonic untuk melakukan ini dalam satu baris kode. Tolong bantu saya.

Cahaya Perak
sumber
1
Versi Python apa yang Anda gunakan?
Mark Byers

Jawaban:

358

Inilah yang dimaksudkan untuk pemahaman daftar :

numbers = [ int(x) for x in numbers ]
adamk
sumber
4
Menunjukkan sintaks yang tidak valid kepada saya
Bugs Buggy
131

Dalam Python 2.x pendekatan lain adalah menggunakan map:

numbers = map(int, numbers)

Catatan: dengan Python 3.x mapmengembalikan objek peta yang bisa Anda konversi ke daftar jika Anda mau:

numbers = list(map(int, numbers))
Mark Byers
sumber
11
Dalam Python 3.x, mapmengembalikan iterator bukan daftar, jadi perlu dituliskan seolah- list(map(int, numbers))olah daftar diperlukan.
kennytm
2
Saya pikir saat ini pendekatan pemahaman daftar sedikit lebih disukai.
extraneon
3
@extraneon: Ya ... atau mungkin mempertimbangkan menggunakan generator, bukan daftar, tergantung pada apa Anda akan menggunakannya. Keuntungan dari generator adalah bahwa jika Anda mungkin tidak perlu melihat semua elemen maka Anda tidak perlu membuang waktu untuk menghitungnya terlebih dahulu.
Mark Byers
4
Diukur dengan timeit dengan Python 2.7.2: LC: 3.578153133392334, peta: 4.9065070152282715
AJJ
1
@ AJJ: mapmemiliki overhead pengaturan yang lebih tinggi, tetapi pada penerjemah referensi, jika fungsi transformasi adalah fungsi bawaan Python diimplementasikan dalam C, ia memiliki biaya per item yang lebih rendah. Menguji input hanya dengan empat nilai tidak akan memberikan informasi yang berguna tentang penskalaan. Yang mengatakan, dalam pengujian saya sendiri (pada Py2.7.12 dan Py3.5.2, yang terakhir dengan list()pembungkus), Py2 dengan mapmenang bahkan untuk empat input elemen, dan kalah dengan hanya selisih kecil pada Py3; Saya menduga tes Anda bengkok mendukung listcomps.
ShadowRanger
21

hanya satu poin,

numbers = [int(x) for x in numbers]

Pemahaman daftar lebih alami, sementara

numbers = map(int, numbers)

lebih cepat.

Mungkin ini tidak masalah dalam banyak kasus

Berguna baca: LP vs peta

renatopp
sumber
6
Bukankah seharusnya angka = peta (int, angka)?
Karan
9

Jika Anda bermaksud meneruskan bilangan bulat itu ke fungsi atau metode, pertimbangkan contoh ini:

sum(int(x) for x in numbers)

Konstruksi ini sengaja sangat mirip dengan daftar pemahaman yang disebutkan oleh adamk. Tanpa tanda kurung siku, itu disebut ekspresi generator , dan merupakan cara yang sangat efisien dalam melewati daftar argumen ke suatu metode. Diskusi yang baik tersedia di sini: Ekspresi Generator vs. Pemahaman Daftar

Tim McNamara
sumber
4

Cara lain untuk membuatnya di Python 3:

numbers = [*map(int, numbers)]

zhukovgreen
sumber
1
Bisakah Anda menjelaskan ini? Saya tidak terbiasa dengan sintaks itu. Terima kasih!
Abalter
1
Saya menggunakan daftar argumen unpacking ( docs.python.org/3/tutorial/… )
zhukovgreen
Aha, python 3 hal. Agak aneh telah []mengambil daftar argumen. Dan, saya tidak tahu Anda bisa melewati iterator sebagai daftar argumen. Saya akan berpikir untuk melakukannya number = list(map(int, numbers)). Tapi terima kasih atas penjelasannya!
Abalter
3

Cara lain,

for i, v in enumerate(numbers): numbers[i] = int(v)
Nick Dandoulakis
sumber
6
OP berkata pythonic
SilentGhost
3
Cara ini sangat berguna jika Anda ingin menjalankan operasi hanya pada beberapa elemen dalam daftar. Ini tidak relevan untuk pertanyaan di utas ini tetapi mungkin ada beberapa kasus saat ini membantu
Dikla
1

Kupikir aku akan menggabungkan jawaban dan menunjukkan beberapa timeithasil.

Python 2 sangat buruk dalam hal ini, tetapi mapsedikit lebih cepat daripada pemahaman.

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
116.25092001434314
>>> timeit.timeit('map(int, l)', setup)
106.66044823117454

Python 3 lebih cepat 4x dari dirinya sendiri, tetapi mengubah mapobjek generator ke daftar masih lebih cepat daripada pemahaman, dan membuat daftar dengan membongkar mapgenerator (terima kasih Artem!) Masih sedikit lebih cepat.

Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> setup = """import random
random.seed(10)
l = [str(random.randint(0, 99)) for i in range(100)]"""
>>> timeit.timeit('[int(v) for v in l]', setup)
25.133059591551955
>>> timeit.timeit('list(map(int, l))', setup)
19.705547827217515
>>> timeit.timeit('[*map(int, l)]', setup)
19.45838406513076

Catatan: Dalam Python 3, 4 elemen tampaknya menjadi titik crossover (3 dalam Python 2) di mana pemahamannya sedikit lebih cepat, meskipun membongkar generator masih lebih cepat daripada daftar dengan lebih dari 1 elemen.

Jim
sumber