วิธีล้างรายการต่างๆ


207

มีเหตุผลใดที่จะทำสิ่งที่ซับซ้อนกว่าหนึ่งในสองบรรทัดนี้เมื่อคุณต้องการล้างรายการใน Python หรือไม่?

old_list = []
old_list = list()

เหตุผลที่ฉันถามคือฉันเพิ่งเห็นสิ่งนี้ในรหัสที่ทำงานอยู่:

del old_list[ 0:len(old_list) ]

1
ทำไมคุณทำเช่นนี้? งานเก็บขยะ ทำไมไม่เพิกเฉยกับค่ารายการเก่าและปล่อยให้ Python ล้างมันโดยอัตโนมัติ
S.Lott

40
@ S.Lott: ผู้โพสต์ไม่ได้เขียนรหัสและถามว่าทำไมนักเขียนดั้งเดิมถึงทำเช่นนั้น
John Fouhy

1
คุณสามารถทำได้: ในขณะที่ l: l.pop ()
RoadieRich

12
ฮ่า ๆ. ฉันแน่ใจว่ามีประสิทธิภาพ
FogleBird

18
ไม่เกี่ยวข้องกับคำถามของคุณ แต่คุณไม่ควรใช้ len เมื่อระบุชิ้น a[:x]หมายถึงการเริ่มต้นที่ x และa[x:]หมายถึง x เพื่อสิ้นสุด สามารถเขียนเป็นa[ 0:len(a) ] a[:]นอกจากนี้คุณยังสามารถใช้ค่าลบเพื่อนับจากท้าย ( a[-1]เป็นองค์ประกอบสุดท้าย)
idbrii

คำตอบ:


356

การล้างรายการในสถานที่จะมีผลต่อการอ้างอิงอื่น ๆ ทั้งหมดของรายการเดียวกัน

ตัวอย่างเช่นวิธีนี้จะไม่ส่งผลกระทบต่อการอ้างอิงอื่น ๆ :

>>> a = [1, 2, 3]
>>> b = a
>>> a = []
>>> print(a)
[]
>>> print(b)
[1, 2, 3]

แต่อันนี้ทำ:

>>> a = [1, 2, 3]
>>> b = a
>>> del a[:]      # equivalent to   del a[0:len(a)]
>>> print(a)
[]
>>> print(b)
[]
>>> a is b
True

คุณสามารถทำได้:

>>> a[:] = []

86
คุณสามารถทำได้del a[:]
idbrii

1
ทำไมครั้งแรกเพียงคนเดียวที่จะส่งผลกระทบa? ฉันคิดaและbอ้างอิงถึงวัตถุเดียวกัน ... แค่อยากรู้ว่าทำไม ขอบคุณ
Alston

37
ด้วยpython 3.3และใหม่กว่าคุณสามารถไปได้ด้วยa.clear()ไม่มีปัญหา!
Marek Lewandowski

4
@ Stallman เพราะในตอนแรกคุณกำลังเปลี่ยนการอ้างอิงสำหรับ 'a' เพื่อชี้ไปที่อาร์เรย์ใหม่ไม่ใช่การล้างหนึ่งและ b ยังคงชี้ไปที่เก่า
Pax0r

4
มันจะดีมากถ้าใครสามารถแสดงความแตกต่างด้านประสิทธิภาพระหว่างวิธีการเหล่านั้น!
Suanmeiguo

37

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

ในการล้างรายการในสถานที่จริงคุณสามารถใช้วิธีใดวิธีหนึ่งต่อไปนี้:

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

ดูหน้าเอกสารประกอบประเภทลำดับที่ไม่แน่นอนสำหรับรายละเอียดเพิ่มเติม


2
ฉันได้ทำการทดสอบแล้วและ alist * = 0 เป็นวิธีที่เร็วที่สุดถัดไปคือ alist.clear () และอีกสองวิธีจะเร็วเท่ากัน คุณช่วยอธิบายได้ไหมว่าทำไมอลิสต์ * = 0 เร็วที่สุด?
Jenny

3
@ เจนนี่: มันใช้opcodesน้อยลง (หรือแพงน้อยกว่า) ภายใต้ประทุน ตัวอย่างเช่นเวอร์ชันโอเปอเรเตอร์ไม่จำเป็นต้องค้นหาชื่อเมธอดหรือบิวด์บิลด์ใด ๆ
Eugene Yarmash

"ควรมีอย่างใดอย่างหนึ่ง - และดีกว่าเพียงหนึ่ง - วิธีชัดเจนที่จะทำ" Python กำลัง
ฉาย

36

มีวิธีง่าย ๆ ในการล้างรายการไพ ธ อน ใช้del list_name [:][:]

ตัวอย่างเช่น:

>>> a = [1, 2, 3]
>>> b = a
>>> del a[:]
>>> print a, b
[] []

13

ดูเหมือนว่าฉันจะให้หน่วยความจำกลับมาให้คุณในขณะที่การกำหนดรายการใหม่จะทำให้รายการเก่าถูกลบเฉพาะเมื่อ gc run.matter

สิ่งนี้อาจมีประโยชน์สำหรับรายการที่มีขนาดใหญ่ แต่สำหรับรายการขนาดเล็กมันควรจะเล็กน้อย

แก้ไข : ในฐานะที่เป็น Algorias มันไม่สำคัญ

สังเกตได้ว่า

del old_list[ 0:len(old_list) ]

เทียบเท่ากับ

del old_list[:]

2
gc ไม่ได้ทำงานเป็นรอบ รายการจะถูกปล่อยให้เป็นอิสระทันทีที่การอ้างอิงครั้งสุดท้ายถูกทิ้ง
Algorias

2
Algorias: เป็นจริงสำหรับ CPython แต่อาจไม่เหมาะกับการใช้งานอื่น ๆ
mhsmith

2
del old_list [0: len (old_list)] และ del old_list [:] มีผลลัพธ์เหมือนกัน แต่อันหลังนั้นเร็วกว่า (ตรวจสอบใน Python 2.6)
Roy Nieterau

6
del list[:] 

จะลบค่าของตัวแปรลิสต์นั้น

del list

จะลบตัวแปรของตัวเองออกจากหน่วยความจำ


5

มีสองกรณีที่คุณอาจต้องการล้างรายการ:

  1. คุณต้องการใช้ชื่อ old_listเพิ่มเติมในรหัสของคุณ
  2. คุณต้องการให้รายการเก่าถูกรวบรวมขยะโดยเร็วที่สุดเพื่อเพิ่มหน่วยความจำ

ในกรณีที่ 1 คุณเพิ่งดำเนินการตามคำแนะนำ:

    old_list = []    # or whatever you want it to be equal to

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

    del old_list

3

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

a = [1, 3, 5, 6]
del a # This will entirely delete a(the list).

แต่ในกรณีที่คุณต้องการอีกครั้งคุณสามารถเริ่มต้นใหม่ได้ หรือเพียงแค่ล้างองค์ประกอบของมันโดย

del a[:]

-4

วิธีแก้ปัญหาอื่นที่ทำงานได้ดีคือการสร้างรายการว่างเปล่าเป็นรายการอ้างอิงที่ว่างเปล่า

empt_list = []

a_list = [1,2,3]ตัวอย่างเช่นคุณมีรายชื่อเป็น เพื่อล้างมันเพียงทำต่อไปนี้:

a_list = list(empt_list)

นี้จะทำให้รายการที่ว่างเปล่าเช่นเดียวกับa_listempt_list


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