[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