tags:

views:

145

answers:

2

On my machine, the execution speed between d.clear() and d={} is over 100ns so am curious why one would use one over the other.

import timeit

def timing():
    d = dict()

if __name__=='__main__':
    t = timeit.Timer('timing()', 'from __main__ import timing')
    print t.repeat()
+18  A: 

The difference is that d = {} creates a new dictionary and d.clear() just empties the dictionary you already have. This subtle difference matters if you have other places in your code holding references to your dictionary. In the first case those other objects won't see any change because you haven't modified the original dictionary. The following code shows this difference in action.

Creating a new dictionary:

>>> d = {'foo': 'bar'}
>>> d2 = d
>>> d = {}
>>> d2
{'foo': 'bar'}

Clearing the existing dictionary:

>>> d = {'foo': 'bar'}
>>> d2 = d
>>> d.clear()
>>> d2
{}
Mark Byers
Why would you want to do that though? Isn't it error-prone?
Tshepang
@Tshepang: Which one do you think is error prone? The one you use depends on what you want to happen.
FogleBird
@FogleBird: the "d2=d"; what situations would you use that?
Tshepang
@Tshepang: I simplified things for example purposes. It's quite possible that you want to pass a reference to a dictionary to another class so that they can use it. Then if you need to change the dictionary then you should decide whether to update the dictionary you've already given out or create a new dictionary and leave the old one as it is. Both alternatives can make sense.
Mark Byers
@Tshepang: Yes, it is error prone. Functional programming avoids stateful objects, so it eliminates lots of bugs. I prefer to only alias a dictionary (or any mutable object) when I need state, or if I want to (temporarily) use a shorter name for readability purposes. Shared state is sometimes a necessary (or convenient) evil.
wisty
@wisty: am still not getting the concept of Functional programming, so what you say goes a bit above my head.
Tshepang
+3  A: 

d={} creates a new dictionary.

d.clear() clears the dictionary.

If you use d={}, then anything pointing to d will be pointing to the old d. This may introduce a bug.

If you use d.clear(), then anything pointing at d will now point at the cleared dictionary, this may also introduce a bug, if that was not what you intended.

Also, I don't think d.clear() will (in CPython) free up memory taken up by d. For performance, CPython doesn't take the memory away from dictionaries when you delete elements, as the usual use for dictionaries is building a big dictionary, and maybe pruning out a few elements. Reassigning memory (and making sure the hash table stays consistent) would take too long in most use cases. Instead, it fills the dictionary with turds (that's the technical term on the mailing list), which indicate that an element used to be there but since got deleted. I'm not entirely sure if d.clear() does this though, but deleting all the keys one by one certainly does.

wisty
spellcheck: "take to long" -> "take too long"
Tshepang