Làm thế nào để trống một danh sách?


356

Có vẻ như "bẩn" làm trống một danh sách theo cách này:

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

Có một cách rõ ràng tồn tại để làm điều đó?


28
Vậy tại sao các bộ và bộ python có một phương thức () rõ ràng, nhưng không liệt kê?
công việc

13
Nhưng nếu có nhiều tham chiếu đến đối tượng, nó có thể hữu ích.
Ned Deily

3
Nó có thể hữu ích nếu tôi cần xóa một danh sách được chia sẻ qua các quy trình trong thời gian chạy và không cần chờ đợi để thu thập dữ liệu (hoặc tôi có sai không? Tôi có hiểu nhầm bộ sưu tập rác không?). Ngoài ra nếu tôi muốn kiểm tra từng phần tử được bật, tôi có thể gỡ lỗi nó trong khi tôi không thể sử dụng lát (hoặc tôi sai). Tôi không cần dừng quá trình thực thi trong khi xóa danh sách của mình.
DrFalk3n

2
@ S.Lott Chỉ vì bạn không hiểu tại sao điều này quan trọng không có nghĩa là phần còn lại của chúng tôi không. Nếu nhiều đối tượng phụ thuộc vào một danh sách chung, nó sẽ có vấn đề. Trong một số mẫu thiết kế này là quan trọng. Người thu gom rác có nghĩa là bạn không phải tự dọn dẹp; nó không phải là một giấy phép để làm cho thêm một mớ hỗn độn.
UpAndAdam

4
Mặc dù có bất kỳ câu trả lời nào khác tốt hơn, mã ban đầu của bạn có thể đã được viết: trong khi alist: alist.pop ()
MrWonderful

Câu trả lời:


570

Điều này thực sự xóa nội dung khỏi danh sách, nhưng không thay thế nhãn cũ bằng danh sách trống mới:

del lst[:]

Đây là một ví dụ:

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

Để hoàn thiện, việc gán lát có tác dụng tương tự:

lst[:] = []

Nó cũng có thể được sử dụng để thu nhỏ một phần của danh sách trong khi thay thế một phần cùng một lúc (nhưng đó là ngoài phạm vi của câu hỏi).

Lưu ý rằng việc thực hiện lst = []không làm trống danh sách, chỉ tạo một đối tượng mới và liên kết nó với biến lst, nhưng danh sách cũ sẽ vẫn có các phần tử tương tự và hiệu ứng sẽ rõ ràng nếu nó có các ràng buộc biến khác.


3
Hai câu hỏi nữa: "del" chính xác là gì? (Tôi suy luận về những thứ khác nhưng tôi thực sự không biết nó là gì) và thứ 2: Làm thế nào để bạn đọc (lớn tiếng) [:]
OscarRyz

2
Để biết giải thích về âm thanh của del, tôi muốn tham khảo các tài liệu: docs.python.org/reference/simple_stmts.html#the-del-statement
fortran

14
Tôi thường không đọc to mã trăn xD, nhưng nếu tôi phải nghĩ rằng tôi sẽ nói "lát từ đầu đến cuối danh sách l".
fortran

2
@jellybean hoàn toàn ngoài ý muốn ^ _ ^ Tiếng Anh không phải là tiếng mẹ đẻ của tôi, vì vậy tôi thực sự không nhận thấy sự tương phản giữa hai bình luận.
fortran

nếu chúng ta làm l = [] sẽ không nội dung danh sách cũ nhận rác được thu thập bởi Python GC?
Alex Punnen 15/03/2016

168

Nếu bạn đang chạy Python 3.3 hoặc cao hơn, bạn có thể sử dụng các clear()phương pháp list, đó là song song với clear()của dict, set, dequevà các loại thùng chứa có thể thay đổi khác:

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

Theo trang tài liệu được liên kết, điều tương tự cũng có thể đạt được với alist *= 0.

Tóm lại, có bốn cách tương đương để xóa danh sách tại chỗ (hoàn toàn trái ngược với Zen của Python !):

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

6
Câu trả lời này phải ở trên cùng, có gì sai với stackoverflow!
BreakBadSP

rõ ràng () là tốt hơn.
sailfish009

61

Bạn có thể thử:

alist[:] = []

Có nghĩa là: Splice trong danh sách [](0 phần tử) tại vị trí [:](tất cả các chỉ mục từ đầu đến cuối)

[:] Là toán tử lát. Xem câu hỏi này để biết thêm thông tin.


4
Tại sao không chỉ alist = []?
mitenka

16
@mitenka không làm trống danh sách, nó ghi đè lên biến alistbằng một danh sách khác sẽ trống. Nếu bất cứ ai khác có một tham chiếu đến danh sách ban đầu, thì nó vẫn như cũ (nghĩa là nó chứa bất cứ thứ gì có trong đó để bắt đầu)
Adam Batkin

@mitenka Một lý do khác là alist.clear()hoặc alist[:] = []giúp kiểm tra đó alistthực sự là một danh sách. Nói rằng bạn đã alisttrở về từ một chức năng foo(). Bạn nghĩ footrả về một danh sách nhưng thực sự nó trả lại a None. Sử dụng alist = []không thể bắt lỗi đó.
aafulei

32

Hóa ra với python 2.5.2, del l[:]chậm hơn một chút so với 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
Trong Python 2.7.2, trên máy của tôi, chúng giống nhau. Cả hai đều chạy từ 13,5-13,7 usec mỗi vòng.
leetNightshade

Bạn cũng nên đo python3 -mtimeit "l = list (phạm vi (1000))" "b = l [:]" để tính "b [:] = []" và "del b [:]". Làm điều đó và lol ...
rockdaboot

1
Tôi đã làm điểm chuẩn với python 3.5 và tôi đồng ý với leetNightshade. .clear(), del b[:]b[:]=[]tất cả chạy cùng ( b[:]=[]là hơi chậm.
Conchylicultor

5
lst *= 0

có tác dụng tương tự như

lst[:] = []

Nó đơn giản hơn một chút và có thể dễ nhớ hơn. Khác hơn là không có nhiều điều để nói

Hiệu quả dường như là như nhau


1
Để hoàn thiện, điều đáng nói là, bất kỳ số nguyên đã cho nào nhỏ hơn hoặc bằng 0sẽ có cùng tác dụng. Mặc dù đây là một mẹo khá gọn gàng, tôi hơi buồn, vì nó không nhận được nhiều sự chú ý ..
Peter Varo

-1
list = []

sẽ thiết lập lại listvào một danh sách trống.

Lưu ý rằng bạn thường không nên bỏ qua các tên hàm dành riêng, chẳng hạn như list, đó là hàm tạo cho một đối tượng danh sách - ví dụ, bạn có thể sử dụng lsthoặc list_thay vào đó.


38
Không: điều này sẽ không sửa đổi danh sách, điều này chỉ gán một danh sách trống cho biến list. Nếu bạn mong đợi một chức năng sửa đổi một danh sách được thông qua (ví dụ), điều này sẽ không làm những gì bạn muốn.
Adam Batkin

10
Không hẳn vậy. Câu hỏi là "Làm thế nào để làm trống danh sách" chứ không phải "Cách gán cho một biến có chứa danh sách"
Adam Batkin

6
câu hỏi không mơ hồ, đoạn trích của op đã đưa các yếu tố ra khỏi danh sách (đó là, sửa đổi nó tại chỗ) ...
fortran

7
Ngoài ra, "danh sách" không nên được sử dụng làm tên biến, vì bóng tối thuộc loại "danh sách". Nhiều nhà phát triển Python sử dụng "L" làm tên biến danh sách, nhưng tôi thích "lst" hơn.
steveha

1
Đôi khi bạn chỉ muốn danh sách trống và điều này tốt như bất kỳ phương pháp nào được đề xuất. Có lẽ còn nhanh hơn nữa
smac89

-3

Một mã đơn giản khác bạn có thể sử dụng (tùy thuộc vào tình huống của bạn) là:

index=len(list)-1

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

Bạn phải bắt đầu chỉ mục ở độ dài của danh sách và đi ngược lại so với chỉ số ở mức 0, vì điều đó sẽ khiến bạn kết thúc với chỉ số bằng với độ dài của danh sách khi nó chỉ bị cắt làm đôi.

Ngoài ra, hãy chắc chắn rằng dòng while có dấu "lớn hơn hoặc bằng". Bỏ qua nó sẽ để lại cho bạn danh sách [0] còn lại.


15
phát minh lại bánh xe với một khối lập phương
CONvid19

Haha. Đây là câu trả lời kỳ lạ thứ hai (+ một bình luận thích hợp) mà tôi đã gặp trên SO. Cần có một trang web cho những điều đáng nhớ này: D
akinuri
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.