ฟังก์ชั่นการโทร int () ในทุกองค์ประกอบรายการ?


184

ฉันมีรายการที่มีสตริงตัวเลขดังนี้:

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

ฉันต้องการแปลงทุกรายการเป็นจำนวนเต็มดังนั้นมันจะมีลักษณะดังนี้:

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

ฉันสามารถทำได้โดยใช้วงเช่น:

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

มันต้องน่าเกลียดเหรอ? ฉันแน่ใจว่ามีวิธี pythonic เพิ่มเติมที่จะทำในรหัสบรรทัดเดียว กรุณาช่วยฉันออกไป.


1
คุณใช้ Python เวอร์ชันใด
Mark Byers

คำตอบ:



131

ใน Python 2.x ใช้วิธีอื่นmap:

numbers = map(int, numbers)

หมายเหตุ: ใน Python 3.x mapจะส่งคืนวัตถุแผนที่ซึ่งคุณสามารถแปลงเป็นรายการได้หากคุณต้องการ:

numbers = list(map(int, numbers))

11
ใน Python 3.x mapส่งคืนตัววนซ้ำแทนรายการดังนั้นจึงจำเป็นต้องเขียนราวกับlist(map(int, numbers))ว่าจำเป็นต้องมีรายการ
kennytm

2
ฉันคิดว่าในปัจจุบันวิธีการเข้าใจรายการเป็นที่นิยมมากขึ้น
extraneon

3
@extraneon: ใช่ ... หรืออาจพิจารณาใช้ตัวสร้างแทนรายการขึ้นอยู่กับว่าคุณจะใช้มันเพื่ออะไร ข้อดีของเครื่องกำเนิดไฟฟ้าคือถ้าคุณไม่จำเป็นต้องดูองค์ประกอบทั้งหมดคุณก็ไม่ต้องเสียเวลาคำนวณมันล่วงหน้า
Mark Byers

4
วัดที่มีอยู่ภายใต้ timeit Python 2.7.2: LC: 3.578153133392334 แผนที่: 4.9065070152282715
Ajj

1
@AJJ: mapมีค่าใช้จ่ายในการตั้งค่าที่สูงกว่า แต่ในล่ามอ้างอิงหากฟังก์ชั่นการแปลงเป็นฟังก์ชันในตัวของ Python ที่ใช้งานใน C จะมีต้นทุนต่อรายการต่ำกว่า การทดสอบอินพุตเพียงสี่ค่าจะไม่ให้ข้อมูลที่เป็นประโยชน์เกี่ยวกับการปรับสเกล ที่กล่าวว่าในการทดสอบของฉันเอง (บน Py2.7.12 และ Py3.5.2, หลังการล้อมรอบlist()), Py2 ที่mapชนะแม้จะมีองค์ประกอบเข้าถึงสี่ส่วนและสูญเสียเพียงเล็กน้อยจาก Py3; ฉันสงสัยว่าการทดสอบของคุณได้รับการวิปริตในความโปรดปรานของ listcomps
ShadowRanger

21

แค่จุด

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

รายการเข้าใจเป็นธรรมชาติมากขึ้นในขณะที่

numbers = map(int, numbers)

เร็วกว่า.

อาจจะไม่สำคัญในกรณีนี้

มีประโยชน์อ่าน: LP เทียบกับแผนที่


6
ไม่ควรเป็น number = map (int, number)?
Karan

9

หากคุณต้องการส่งจำนวนเต็มไปยังฟังก์ชันหรือเมธอดให้พิจารณาตัวอย่างนี้:

sum(int(x) for x in numbers)

การก่อสร้างนี้มีเจตนาคล้ายกับรายการที่กล่าวถึงโดย adamk หากไม่มีเครื่องหมายวงเล็บเหลี่ยมจะเรียกว่านิพจน์ตัวสร้างและเป็นวิธีที่มีประสิทธิภาพในหน่วยความจำมากในการส่งรายการอาร์กิวเมนต์ไปยังเมธอด การอภิปรายที่ดีมีอยู่ที่นี่: นิพจน์ตัวสร้างเปรียบเทียบกับความเข้าใจในรายการ


4

อีกวิธีในการสร้างใน Python 3:

numbers = [*map(int, numbers)]


1
คุณอธิบายได้ไหม ฉันไม่คุ้นเคยกับไวยากรณ์นั้น ขอบคุณ!
ปิดบัง

1
ฉันใช้การเอาออกรายการข้อโต้แย้ง ( docs.python.org/3/tutorial/... )
zhukovgreen

อ๊ะเป็นงูหลาม 3 ดูเหมือนว่าจะมี[]รายการโต้แย้ง และฉันไม่รู้ว่าคุณสามารถส่งตัววนซ้ำเป็นรายการอาร์กิวเมนต์ได้ number = list(map(int, numbers))ผมจะมีความคิดที่จะทำ แต่ขอบคุณสำหรับคำอธิบาย!
ปิดบัง

3

อีกทางหนึ่ง

for i, v in enumerate(numbers): numbers[i] = int(v)

6
OP กล่าวว่าpythonic
SilentGhost

3
วิธีนี้มีประโยชน์มากหากคุณต้องการดำเนินการกับองค์ประกอบบางอย่างในรายการเท่านั้น สิ่งนี้ไม่เกี่ยวข้องกับคำถามในหัวข้อนี้ แต่อาจมีบางกรณีที่มีประโยชน์
Dikla

1

คิดว่าฉันจะรวบรวมคำตอบและแสดงtimeitผลลัพธ์บางอย่าง

Python 2 แย่มากที่นี่ แต่mapเร็วกว่าความเข้าใจนิดหน่อย

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 เร็วกว่าตัวมันเองถึง 4 เท่า แต่การแปลงmapออบเจ็กต์ตัวสร้างไปยังลิสต์นั้นยังเร็วกว่าความเข้าใจและการสร้างลิสต์โดยการเอาตัวmapกำเนิดออกมา(ขอบคุณ Artem!) ก็ยังเร็วขึ้นเล็กน้อย

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

หมายเหตุ: ใน Python 3 องค์ประกอบ 4 ดูเหมือนจะเป็นจุดไขว้ (3 ใน Python 2) โดยที่ความเข้าใจนั้นเร็วขึ้นเล็กน้อยแม้ว่าการคลายตัวกำเนิดยังคงเร็วกว่าทั้งรายการที่มีองค์ประกอบมากกว่า 1 รายการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.