Hello!
I want to know how to delete all the items (in a list) beautifully?
For example: list = [2, 3, 4]
Can I just do it in this way? list = [] ![]()
Or del list[2], del list[1], del list[0] ![]()
Thank you for your time!
del list[:]
Thanks so much!
For the record list.clear() does the same thing.
Also naming a variable list is not a good practice, as list is a buitin that is used to build lists.
Just to note, this does not delete any items in the list. It simply creates a new empty list and assigns it to the name list. Perhaps list was the only reference to the old list, and it will be reclaimed now that its reference count is 0, but any other references will still see the original list [2, 3, 4].
x = [1,2,3]
y = x
x = []
assert y == [1,2,3]
Using list.clear() guarantees that the list itself is emptied, and all references (not just list) will see the list as empty. (So would del list[:]; Iâm not aware of any significant difference in semantics.)
You are right! Thanks!
Thatâs right! I understand now, thanks so much
Thank you!
WOW, so does Python also have the function of âgarbage collectionâ like Java? Thatâs great!
As a heads-up, you can click the heart icon on posts to âlikeâ them instead of writing separate personalized thank-you notes. (And yes, Python is a garbage-collected language.)
del list slice always existed. dicts with started with or gained .clear to abbreviate deleting each key (and value) in a list. Beginners used list.clear by analogy so it was eventually added instead of raising NameError. So there are 2 obvious ways, depending on where one starts.
In my view, deleting a slice isnât obvious - it requires a bit of lateral thinking if you havenât seen it before. Calling clear is a lot more obvious even if you havenât seen it on analogous things - itâs a coherent, specific thing youâd want to do with the list, so thereâs a reasonable expectation of the functionality being built-in. A separate function wouldnât work because the operation is inherently mutating, whereas some containers are immutable.
For that matter, deleting a slice isnât the only âlateral thinkingâ option, either. For example, one could use slice assignment: mylist[:] = [].
So, for a while the language was missing what it âshouldâ have had. Which happens; we canât all be Dutch (or not) ![]()
Why bless you, it all depends!
How do you remove one thing from a list? del stuff[3] How do you remove a set of things from a list? del stuff[2:4] How do you remove all from the beginning, or all to the end? del stuff[:2] and del stuff[4:] So how do you remove them all? del stuff[:]
I have become very happily accustomed to âprojectionâ notations. Itâs the same kind of idea of âdo this on everythingâ. In Pike, for example, I can refer to one array element as func(stuff[3]) or all array elements with func(stuff[*]) - it calls the function with every element and returns an array with the results. Pythonâs slice notation is the same thing, but more flexible, since you can make partial slices (although I will admit, stuff[:] isnât nearly as obvious for the âall itemsâ case as stuff[*] is). If youâre used to working with subscripts âin bulkâ, so to speak, it makes a lot of sense, and makes so many algorithms so much easier to work with.
list *= 0
Not that it makes much of a difference (we are talking about a few dozen ns here), but for small lists list.clear() is about 3x faster
than del list[:] (Python3.11 on Linux).
How small and how did you measure?
My results with lst = list(range(5)):
7.4 ± 0.0 ns pass # as baseline
30.3 ± 0.1 ns lst.clear()
47.9 ± 0.1 ns lst *= 0
67.0 ± 0.2 ns del lst[:]
76.4 ± 0.2 ns lst[:] = ()
94.6 ± 0.2 ns lst[:] = []
Python: 3.11.4 (main, Sep 9 2023, 15:09:21) [GCC 13.2.1 20230801]
script
from timeit import timeit
from statistics import mean, stdev
import sys
import random
funcs = '''\
lst.clear()
del lst[:]
lst[:] = []
lst[:] = ()
lst *= 0
pass # as baseline
'''.splitlines()
times = {f: [] for f in funcs}
def stats(f):
ts = [t * 1e9 for t in sorted(times[f])[:10]]
return f'{mean(ts):5.1f} ± {stdev(ts):3.1f} ns '
for _ in range(100):
random.shuffle(funcs)
for f in funcs:
t = timeit(
'for lst in lists: ' + f,
'lst = list(range(5)); lists = [lst[:] for _ in range(10**4)]',
number=1
) / 10**4
times[f].append(t)
for f in sorted(funcs, key=stats):
print(stats(f), f)
print('\nPython:', sys.version)
I tested for the empty list and range(10). To measure small snippets of code I tend to use ipython %timeit feature, that runs loops to properly measure execution time. To profile larger things I recommend using a proper profiler.
With range(10), how did you avoid that %timeitâs loop repeatedly cleared the same list, i.e., that it didnât really clear any elements in loop iterations after the first?