[PATCH] Re: frozenset() without arguments should return a singleton

Raymond Hettinger vze4rx4y at verizon.net
Sat Feb 12 19:15:39 EST 2005


> > It is not quite correct to say that this is what all immutables do:
> >
> >.>>>x = 500
> >.>>>y = 600 - 100
> >.>>>x is y
> > False
>
> I know. The same is true for concateneted strings, etc. But whenever an
> immutable object is created directly ('by hand'), it holds. It also holds,
> btw, for tuple() - as opposed to ().

That is an implementation detail, not guaranteed by the language (i.e. not
necessarily true in future versions, in Jython, or other implementations).  It
is just an optimization that made sense for tuples but not necessarily for other
immutables.



> I actually use frozensets whenever I know that my set is going to be immutable
> (I thought that was what they were meant for).

That is a reasonable use.  I like it because it is explicit about your intent.

Guido, on the other hand, would probably object because it is akin to saying
that () should be passed for an empty list in situations where the list is
expected not to mutate.



> And similar to the usage of tuples as replacements for empty lists, I
> definitely pass a frozenset whenever I need a dummy set-like object.
> If I know that frozenset() is not constant, I may end up with keeping a dummy
> reference around somewhere that is passed instead of a 'new' frozenset().

That solution is reasonable and portable:

emptyset = frozenset()
f('abc', emptyset)
g('def', emtpyset)
h(1, 2, emtpyset, True)
 . . .

I also find it be more readable than:

f('abc', frozenset())
g('def', frozenset())
h(1, 2, emtpyset, frozenset())

FWIW, the latter form entails three failed lookups into the local scope and
three successful lookups in the __builtin__ scope.  Since the former can store
emptyset as a local variable, it can be accessed with no lookups at all.  Also,
the latter forms incur extra trips around the eval-loop and call-function
overhead.

IOW, yoursavings = time_to_allocate_an_emtpy_set - builtin_lookup_time -
eval_loop_and_call_overhead - extra_time_building_non_emtpy_sets.  I suspect the
net savings to be near zilch.




> Also, I don't know what else needs to be changed and what a difference that
> makes. But if the added code is reasonably limited, I'd vote for it.

Will think about it for a while.  I'm not terribly opposed to the idea.  I just
find the case for it to be somewhat weak.  Also, I'm not sure it warrants the
effort, the code clutter, or introducing issues like having a semantic
difference between the result of frozenset() and the result of frozenset([]).




Raymond Hettinger





More information about the Python-list mailing list