[Python-3000] sets in P3K?

Guido van Rossum guido at python.org
Thu Apr 27 01:08:06 CEST 2006


On 4/26/06, Josiah Carlson <jcarlson at uci.edu> wrote:
> Indeed, but only with immutable iterable sequences.  Mutable iterable
> sequences are unambiguous (they don't hash(), so can't be an entry in
> and of themselves).

Unfortunately, generator expressions happen to have a (useless) hash value.

> def _set(*args):
>     if len(args) > 1:
>         #one unambiguous case
>         return set(args)
>     arg = args[0]
>     try:
>         #catches non-sequences
>         _ = iter(arg)
>     except TypeError:
>         #another unambiguous case
>         return set((arg,))
>     try:
>         #catches mutable sequences
>         _ = hash(arg)
>     except:
>         #unambiguous for non-hashables
>         return set(arg)
>     else:
>         #ambiguous for any immutable iterable sequence...
>         return set(arg)

This is extremely distasteful. Catching exceptions in order to detect
what to do is an approach of last resort, when you've otherwise
painted yourself into a bad corner; it has a high probability of at
some point hiding a genuine exception that should have triggered a
traceback instead of the code taking a different behavior. This is
well-documented.

Also, it's deadly for code readability(). When we see set(x) we won't
know what was intended unless we know a lot about the type of x. We'd
get the same problems we have today with "...%s..." % x where x
happens to be a tuple under certain circumstances.

This kind of proposal might fly in a statically typed language. It
doesn't work in Python.

> However, being that this is the Py3k list, and the only ambiguous case
> is that of a single immutable sequence argument to set(), we could
> state an execution semantic and call it sufficient.

Choosing a semantic doesn't help if it is confusing or likely to hide bugs.

> Being that set(<immutable iterable sequence>) right now results in the
> insertion of each item from that sequence into a new set (set((1,2)) ->
> set([1,2]) ), we wouldn't need to change the obvious (at least to some)
> meaning, or really "the way it works now" meaning.
>
> On the other hand, I note that both Raymond and Guido are saying -1, so
> I'll not push it (though I'm also still against more literal syntax),
> even though one can come to an almost obvious signature.

Right. I'll stop now too; we all know where we stand and in *this*
case the BDFL's opinion still prevails. :-)

> > I find the many attempts to come up with a reasonable way to construct
> > a set from a list of given values; I hope that {x, y} can still come
> > out as a winner, with set(x) useful to construct a set from a
> > pre-existing iterable. Note that set(range(10)) is a set with 10
> > elements; {range(10)} of course would be a set with one element.
>
> Or really {tuple(range(10))}?

I didn't say what the type of that element would be. Even today,
[xrange(10), xrange(20)] is a totally valid expression. In Python
3000, {range(10)} would mean what you'd write today as
set([xrange(10)]).

--
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list