[Python-Dev] Set options

Ka-Ping Yee ping@lfw.org
Mon, 20 Mar 2000 08:34:12 -0600 (CST)


I think that at this point the possibilities for doing sets
come down to four options:


1. use lists

    visible changes:   new methods l.include, l.exclude

    invisible changes: faster 'in'

    usage:             s = [1, 2], s.include(3), s.exclude(3),
                       if item in s, for item in s

2. use dicts

    visible changes:   for/if x in dict means keys
                       accept dicts without values (e.g. {1, 2})
                       new special non-printing value ": Present"
                       new method d.insert(x) means d[x] = Present

    invisible changes: none

    usage:             s = {1, 2}, s.insert(3), del s[3],
                       if item in s, for item in s

3. new type

    visible changes:   set() built-in
                       new <type 'set'> with methods .insert, .remove

    invisible changes: none

    usage:             s = set(1, 2), s.insert(3), s.remove(3)
                       if item in s, for item in s

4. do nothing

    visible changes:   none

    invisible changes: none

    usage:             s = {1: 1, 2: 1}, s[3] = 1, del s[3],
                       if s.has_key(item), for item in s.keys()



Let me say a couple of things about #1 and #2.  I'm happy with both.
I quite like the idea of using dicts this way (#2), in fact -- i
think it was the first idea i remember chatting about.

If i remember correctly, Guido's objection to #2 was that "in" on
a dictionary would work on the keys, which isn't consistent with
the fact that "in" on a list works on the values.

However, this doesn't really bother me at all.  It's a very simple
rule, especially when you think of how people understand dictionaries.
If you hand someone a *real* dictionary, and ask them

    Is the word "python" in the dictionary?
    
they'll go look up "python" in the *keys* of the dictionary (the
words), not the values (the definitions).

So i'm quite all right with saying

    for x in dict:

and having that loop over the keys, or saying

    if x in dict:

and having that check whether x is a valid key.  It makes perfect
sense to me.  My main issue with #2 was that sets would print like

    {"Alice": 1, "Bob": 1, "Ted": 1}

and this would look weird.  However, as Greg explained to me, it
would be possible to introduce a default value to go with set
members that just says "i'm here", such as 'Present' (read as:
"Alice" is present in the set) or 'Member' or even 'None', and
this value wouldn't print out -- thus

    s = {"Bob"}
    s.include("Alice")
    print s

would produce

    {"Alice", "Bob"}

representing a dictionary that actually contained

    {"Alice": Present, "Bob": Present}

You'd construct set constants like this too:

    {2, 4, 7}

Using dicts this way (rather than having a separate set type
that just happened to be spelled with {}) avoids the parsing
issue: no need for look-ahead; you just toss in "Present" when
the text doesn't supply a colon, and move on.

I'd be okay with this, though i'm not sure everyone would; and
together with Guido's initial objection, that's what motivated me
to propose the lists-as-sets thing: fewer changes all around, no
ambiguities introduced -- just two new methods, and we're done.

Hmm.

I know someone who's just learning Python.  I will attempt to
ask some questions about what she would find natural, and see
if that reveals anything interesting.


-- ?!ng