การสร้างรายการว่างใน Python


243

วิธีที่ดีที่สุดในการสร้างรายการว่างใหม่ใน Python คืออะไร?

l = [] 

หรือ

l = list()

ฉันถามสิ่งนี้เพราะสองสาเหตุ:

  1. เหตุผลทางเทคนิคซึ่งเป็นสิ่งที่เร็ว (การสร้างคลาสทำให้เกิดค่าใช้จ่ายหรือไม่)
  2. ความสามารถในการอ่านโค้ด - อันไหนเป็นแบบแผนมาตรฐาน

4
"เร็วขึ้น"? ทำไมคุณไม่รัน timeit?
S.Lott

คำตอบ:


335

นี่คือวิธีที่คุณสามารถทดสอบว่าโค้ดใดเร็วกว่า:

% python -mtimeit  "l=[]"
10000000 loops, best of 3: 0.0711 usec per loop

% python -mtimeit  "l=list()"
1000000 loops, best of 3: 0.297 usec per loop

อย่างไรก็ตามในทางปฏิบัติการเริ่มต้นนี้น่าจะเป็นส่วนเล็ก ๆ ของโปรแกรมของคุณดังนั้นการกังวลเกี่ยวกับเรื่องนี้อาจเป็นเรื่องที่ผิด

การอ่านเป็นเรื่องส่วนตัวมาก ฉันชอบ[]แต่คนที่มีความรู้มากเช่น Alex Martelli ชอบlist()เพราะออกเสียงได้


12
ว้าวขอบคุณสำหรับการทำโปรไฟล์ ฉันอยากรู้อยู่เสมอว่ามันเป็นอย่างไร
user225312

ทำไมไม่list('')ให้[]แทน['']?
Chris_Rands

นี่เป็นเพราะฟังก์ชั่นนี้สร้างรายการจากประเภทที่กำหนดได้คุณไม่สามารถแทรกในอาร์กิวเมนต์มากกว่า 1 รายการ (ลองพิมพ์list('abcd')แล้วคุณเข้าใจทุกอย่าง)
Ivan Lavrenov

133

list()ช้ากว่า[]เพราะโดยธรรมชาติ

  1. มีการค้นหาสัญลักษณ์ (ไม่มีวิธีใดที่หลามจะรู้ล่วงหน้าหากคุณไม่ได้กำหนดรายการใหม่เพื่อให้เป็นอย่างอื่น!)

  2. มีการเรียกใช้ฟังก์ชัน

  3. จากนั้นจะต้องตรวจสอบว่ามีข้อโต้แย้งที่ผ่าน iterable (เพื่อให้สามารถสร้างรายการที่มีองค์ประกอบจากมัน) ps ไม่มีในกรณีของเรา แต่มี "ถ้า" ตรวจสอบ

ในกรณีส่วนใหญ่ความแตกต่างความเร็วจะไม่สร้างความแตกต่างในทางปฏิบัติใด ๆ


38
+1: รู้สึกดีที่เข้าใจว่าทำไมlist()ช้ากว่า[]!
Eric O Lebigot

2
ในกรณีที่list()มีเพียงเพื่อตรวจสอบว่ามีข้อโต้แย้งใด ๆ เลย ... "ตรวจสอบว่า iterable" และ "สร้างรายการที่มีองค์ประกอบ" ก็ไม่ได้เกิดขึ้น; พวกเขาใช้เฉพาะในกรณีที่มีหาเรื่อง มันเป็นไปได้แม้กระทั่งว่ารหัส C สำหรับ[]สาย C list()รหัสเดียวกับ ไม่ว่าในกรณีใดเวลาที่ใช้ใน (c) จะน้อยเมื่อเทียบกับ (a) + (b)
John Machin

1
@ John Machin - ขอโทษด้วยความสับสนสิ่งที่ฉันหมายถึงใน (c) คือว่ามันจะต้องตรวจสอบว่ามีการโต้แย้งใช่ ส่วนที่เหลือเป็นเรื่องเกี่ยวกับสิ่งที่จะเกิดขึ้นหากมีการโต้แย้งซึ่งในกรณีของเราไม่มี
Nas Banov

16

[]ฉันใช้

  1. เร็วกว่าเพราะสัญกรณ์รายการเป็นไฟฟ้าลัดวงจร
  2. การสร้างรายการด้วยไอเท็มควรมีลักษณะเหมือนกับการสร้างรายการโดยไม่ต้องทำไมต้องมีความแตกต่าง

3

ฉันไม่รู้จริงๆเกี่ยวกับเรื่องนี้ แต่ดูเหมือนว่าสำหรับฉันโดยประสบการณ์แล้ว jpcgt นั้นถูกต้องแล้ว ตัวอย่างต่อไปนี้: ถ้าฉันใช้รหัสต่อไปนี้

t = [] # implicit instantiation
t = t.append(1)

ในล่ามแล้วโทร t ให้ฉันเพียง "t" โดยไม่มีรายการใด ๆ และถ้าฉันผนวกสิ่งอื่นเช่น

t = t.append(2)

ฉันได้รับข้อผิดพลาด "วัตถุไม่มีประเภท" ไม่มีแอตทริบิวต์ "ผนวก" " อย่างไรก็ตามถ้าฉันสร้างรายการโดย

t = list() # explicit instantiation

จากนั้นก็ใช้งานได้ดี


15
มันเป็นเพราะว่า t.append(1)ปรับเปลี่ยนtในสถานที่ก็ไม่ได้อะไร แต่กลับNoneและคุณกำลังกำหนดนี้ไปNone tดังนั้นtอ้างอิงตอนนี้Noneแทนที่จะไปที่รายการ ความผิดพลาดของคุณที่นี่คือการเขียนแทนเพียงt=t.append(1) t.append(1)คุณจะสังเกตเห็นพฤติกรรมเดียวกันกับlist()ดังนั้นจึงไม่มีความแตกต่างที่นี่
Darkonaut

1

เพียงเพื่อเน้น @Darkonaut คำตอบเพราะฉันคิดว่ามันควรจะมองเห็นได้มากขึ้น

new_list = []หรือnew_list = list()ทั้งคู่ก็ดี (ไม่สนใจประสิทธิภาพ) แต่append()ส่งคืนNoneเนื่องจากคุณไม่สามารถทำได้new_list = new_list.append(somethingเป็นผลคุณไม่สามารถทำ

ฉันงงมากกับการตัดสินใจแบบย้อนกลับ yuck

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