จะล้างรายการได้อย่างไร


356

ดูเหมือนว่า "สกปรก" การล้างรายการด้วยวิธีนี้:

while len(alist) > 0 : alist.pop()

มีวิธีที่ชัดเจนในการทำเช่นนั้นหรือไม่?


28
ดังนั้นทำไมหลามพจน์และเซตจึงมีเมธอด clear () แต่ไม่ใช่รายการ?
งาน

13
แต่ถ้ามีการอ้างอิงไปยังวัตถุหลายรายการอาจเป็นประโยชน์
เน็ด Deily

3
มันอาจจะมีประโยชน์ถ้าฉันต้องการล้างรายการที่ใช้ร่วมกันผ่านกระบวนการที่รันไทม์และไม่จำเป็นต้องรอ garbaging (หรือฉันผิดฉันถูกเข้าใจผิดว่าเก็บขยะ?) นอกจากนี้หากฉันต้องการตรวจสอบองค์ประกอบที่ดึงขึ้นมาแต่ละตัวฉันสามารถดีบักได้ในขณะที่ฉันไม่สามารถใช้การแบ่งส่วนได้ (หรือฉันผิด) ฉันไม่จำเป็นต้องหยุดการประมวลผลขณะล้างรายการของฉัน
DrFalk3n

2
@ S.Lott เพียงเพราะคุณไม่เข้าใจว่าทำไมสิ่งนี้สำคัญไม่ได้หมายความว่าพวกเราที่เหลือไม่ได้ หากวัตถุหลายรายการขึ้นอยู่กับรายการทั่วไปมันจะมีความสำคัญ ในรูปแบบการออกแบบที่หลากหลายนี้เป็นสิ่งสำคัญ นักสะสมขยะหมายความว่าคุณไม่ต้องทำความสะอาดตัวเอง มันไม่ใช่ใบอนุญาตที่จะทำให้เป็นระเบียบมากขึ้น
UpAndAdam

4
แม้ว่าจะมีคำตอบอื่น ๆ ที่ดีกว่ารหัสเริ่มต้นของคุณก็สามารถเขียนได้: ในขณะที่ alist: alist.pop ()
MrWonderful

คำตอบ:


570

สิ่งนี้จะลบเนื้อหาออกจากรายการ แต่จะไม่แทนที่ป้ายกำกับเก่าด้วยรายการเปล่าใหม่:

del lst[:]

นี่คือตัวอย่าง:

lst1 = [1, 2, 3]
lst2 = lst1
del lst1[:]
print(lst2)

เพื่อความสมบูรณ์การมอบหมายชิ้นมีผลเหมือนกัน:

lst[:] = []

นอกจากนี้ยังสามารถใช้เพื่อย่อส่วนของรายการในขณะที่เปลี่ยนชิ้นส่วนในเวลาเดียวกัน (แต่ไม่อยู่นอกขอบเขตของคำถาม)

โปรดทราบว่าการทำlst = []ไม่ได้ทำให้รายการว่างเปล่าเพียงแค่สร้างวัตถุใหม่และผูกกับตัวแปรlstแต่รายการเก่าจะยังคงมีองค์ประกอบเดียวกันและเอฟเฟกต์จะปรากฏหากมีการผูกตัวแปรอื่น ๆ


3
อีกสองคำถาม: "del" คืออะไรกันแน่ (ฉันอนุมานมัน del-etes สิ่งต่าง ๆ แต่ฉันไม่รู้จริง ๆ ว่ามันคืออะไร) และ 2nd: คุณอ่านอย่างไร (ดัง) [:]
OscarRyz

2
สำหรับคำอธิบายที่ชัดเจนเกี่ยวกับ del ฉันต้องการดูเอกสาร: docs.python.org/reference/simple_stmts.html#the-del-statement
fortran

14
ฉันมักจะไม่อ่านรหัสหลามเสียงดัง xD แต่ถ้าฉันต้องฉันคิดว่าฉันจะพูดว่า "ชิ้นจากจุดเริ่มต้นไปยังจุดสิ้นสุดของรายการ l"
fortran

2
@ jellybean ไม่ได้ตั้งใจอย่างสมบูรณ์ ^ _ ^ ภาษาอังกฤษไม่ใช่ภาษาแม่ของฉันดังนั้นฉันจึงไม่ได้สังเกตเห็นความแตกต่างระหว่างสองความคิดเห็น
Fortran

ถ้าเราทำ l = [] เนื้อหาในรายการเก่าจะไม่ถูกรวบรวมโดย Python GC หรือ
Alex Punnen

168

หากคุณกำลังใช้งูหลาม 3.3 หรือดีกว่าคุณสามารถใช้clear()วิธีการlistซึ่งขนานกับclear()ของdict, set, dequeและอื่น ๆ ประเภทภาชนะไม่แน่นอน:

alist.clear()  # removes all items from alist (equivalent to del alist[:])

alist *= 0ตามหน้าเอกสารประกอบการเชื่อมโยงที่สามารถเดียวกันยังทำได้ด้วย

สรุปแล้วมีวิธีที่เทียบเท่าสี่วิธีในการล้างรายการในสถานที่ (ค่อนข้างตรงข้ามกับZen of Python !):

  1. alist.clear() # Python 3.3+
  2. del alist[:]
  3. alist[:] = []
  4. alist *= 0

6
คำตอบนี้ควรจะอยู่ที่ด้านบนเกิดอะไรขึ้นกับ stackoverflow!
BreakBadSP

ชัดเจน () ดีกว่า
sailfish009

61

คุณสามารถลอง:

alist[:] = []

ซึ่งหมายความว่า: ประกบกันในรายการ[](0 องค์ประกอบ) ที่ตำแหน่ง[:](ดัชนีทั้งหมดตั้งแต่ต้นจนจบ)

[:] เป็นตัวดำเนินการชิ้น ดูคำถามนี้สำหรับข้อมูลเพิ่มเติม


4
ทำไมไม่เป็นเช่นนั้นalist = []?
mitenka

16
@mitenka ที่ไม่ทำให้รายการว่าง แต่จะเขียนทับตัวแปรalistด้วยรายการอื่นซึ่งเกิดขึ้นเป็นค่าว่าง ถ้าใครมีการอ้างอิงถึงรายการเดิมที่ยังคงเป็นคือ (คือมันมีสิ่งที่อยู่ในนั้นจะเริ่มต้นด้วย)
อดัม Batkin

@mitenka อีกเหตุผลหนึ่งคือalist.clear()หรือalist[:] = []ช่วยตรวจสอบว่าalistเป็นรายการอย่างแท้จริง สมมติว่าคุณได้รับกลับมาจากฟังก์ชั่นalist foo()คุณคิดว่าfooส่งคืนรายการ แต่จริง ๆ แล้วส่งคืนNoneรายการ การใช้alist = []ไม่สามารถเข้าใจความผิดพลาดนั้นได้
aafulei

32

ปรากฎว่าด้วย python 2.5.2 del l[:]ช้ากว่าl[:] = []1.1 usec เล็กน้อย

$ python -mtimeit "l=list(range(1000))" "b=l[:];del b[:]"
10000 loops, best of 3: 29.8 usec per loop
$ python -mtimeit "l=list(range(1000))" "b=l[:];b[:] = []"
10000 loops, best of 3: 28.7 usec per loop
$ python -V
Python 2.5.2

1
ใน Python 2.7.2 บนเครื่องของฉันมันเหมือนกัน พวกเขาทั้งคู่วิ่งจาก 13.5-13.7 usec ต่อวง
leetNightshade

คุณควรวัด python3 -mtimeit "l = list (ช่วง (1000))" "b = l [:]" เพื่อคำนวณ "b [:] = []" และ "del b [:]" ทำได้แล้วฮ่า ๆ ...
rockdaboot

1
ฉันทำเกณฑ์มาตรฐานด้วย python 3.5 และฉันเห็นด้วยกับ leetNightshade .clear(), del b[:]และb[:]=[]วิ่งเหมือนกันทั้งหมด ( b[:]=[]เป็นช้าลงเล็กน้อย.
Conchylicultor

5
lst *= 0

มีผลเช่นเดียวกับ

lst[:] = []

มันง่ายกว่าเล็กน้อยและอาจจำได้ง่ายกว่า นอกเหนือจากนั้นไม่มีอะไรจะพูดมาก

ประสิทธิภาพดูเหมือนจะใกล้เคียงกัน


1
เพื่อความสมบูรณ์นั้นมีค่าควรแก่การกล่าวถึงว่าจำนวนเต็มใดก็ตามที่น้อยกว่าหรือเท่ากับ0จะมีผลเหมือนกัน มันเป็นเคล็ดลับที่ค่อนข้างเรียบร้อยฉันเสียใจนิดหน่อยที่มันไม่ได้รับความสนใจมากนัก
ปีเตอร์ Varo

-1
list = []

จะรีเซ็ตlistเป็นรายการว่าง

โปรดทราบว่าโดยทั่วไปคุณไม่ควรใช้ชื่อฟังก์ชันที่สงวนไว้ของเงาเช่นlistซึ่งเป็นตัวสร้างสำหรับรายการวัตถุ - คุณสามารถใช้lstหรือlist_แทนตัวอย่างเช่น


38
No: listนี้จะไม่ปรับเปลี่ยนรายการนี้ก็จะกำหนดรายการที่ว่างเปล่าให้กับตัวแปร หากคุณคาดหวังให้ฟังก์ชันแก้ไขรายการส่งผ่าน (ตัวอย่าง) สิ่งนี้จะไม่ทำสิ่งที่คุณต้องการ
Adam Batkin

10
ไม่ได้จริงๆ คำถามคือ "วิธีการล้างรายการ" ไม่ "วิธีการกำหนดมากกว่าตัวแปรที่มีรายการ"
อดัม Batkin

6
คำถามคือไม่คลุมเครือข้อมูลโค้ดของสหกรณ์ที่ถูก popping องค์ประกอบออกจากรายการ (ที่มันปรับเปลี่ยนในสถานที่) ...
Fortran

7
นอกจากนี้ไม่ควรใช้ "รายการ" เป็นชื่อตัวแปรเนื่องจากเป็นเงาประเภท "รายการ" นักพัฒนา Python หลายคนใช้ "L" เป็นชื่อตัวแปรของรายการ แต่ฉันชอบ "lst"
steveha

1
บางครั้งคุณเพียงแค่ต้องการให้รายการว่างเปล่าและนี่ก็เป็นวิธีที่ดีตามที่เสนอ น่าจะเป็นเร็วกว่านี้
smac89

-3

อีกรหัสง่าย ๆ ที่คุณสามารถใช้ได้ (ขึ้นอยู่กับสถานการณ์ของคุณ) คือ:

index=len(list)-1

while index>=0:
    del list[index]
    index-=1

คุณต้องเริ่มต้นดัชนีที่ความยาวของรายการและย้อนกลับไปเทียบกับดัชนีที่ 0 เป็นต้นไปเพราะนั่นจะทำให้คุณมีดัชนีเท่ากับความยาวของรายการโดยจะถูกตัดครึ่งเท่านั้น

นอกจากนี้ตรวจสอบให้แน่ใจว่าในขณะที่บรรทัดมีเครื่องหมาย "มากกว่าหรือเท่ากับ" การข้ามไปจะทำให้คุณเหลือรายการ [0]


15
reinventing ล้อด้วยลูกบาศก์
CONVid19

ฮ่าฮ่า นี่คือคำตอบแปลก ๆ ที่สอง (+ ความคิดเห็นที่เหมาะสม) ที่ฉันได้พบใน SO ควรมีเว็บไซต์สำหรับสิ่งที่น่าจดจำเหล่านี้: D
akinuri
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.