[Python-Dev] Retrieve an arbitrary element from a set without removing it

Chris Bergstresser chris at subtlety.com
Mon Oct 26 19:54:03 CET 2009


On Mon, Oct 26, 2009 at 11:38 AM, Guido van Rossum <guido at python.org> wrote:
> - If sets were to grow an API to non-destructively access the object
> stored in the set for a particular key, then dicts should have such a
> method too.
>
> - Ditto for an API to non-destructively get an arbitrary element.
>
> - I'm far from convinced that we urgently need either API. But I'm
> also not convinced it's unneeded.

   These clearly aren't urgently needed, but I do think they're needed
and useful.  For those who want a use-case for getting an arbitrary
element from a set, I've run into the need several times over the last
year, and each time I'm a little surprised I had the need and a little
surprised there wasn't an good way of going about it.
   In the most recent example, I was writing some UI code.  I had a
set of all the open window references so I could clean them up at the
end of the program.  I needed to call some API function that required
a window reference as the first argument, but it returned a global
value common to all the window references.

   I like the proposed set.get() method, personally.  list.get(index)
gets the item at that index, dict.get(key) gets the item associated
with that key, set.get() gets an item, but doesn't place any
guarantees on which item is returned.  Makes sense to me.  I also like
the idea there aren't any guarantees about which item is returned--it
allows subclasses to implement different behavior (so one might always
return the last item placed in the set, another could always return a
random item, another could implement some round-robin behavior, and
all would fulfill the contract of the set class).
   The existing methods aren't great for accomplishing this, mainly
because they're obfuscatory.  "iter(s).next()" is probably clearest,
and at least will throw a StopIteration exception if the set is empty.
 "for x in s: break" is just confusing, easy to accidentally confuse
with "for x in s: pass", and causes an unrevealing NameError if the
set is empty.  Add in all the other idioms for accomplishing the same
thing ("x, = s", etc.) and I think there's a good argument for adding
the method to sets, if only to provide a single obvious way of doing
it--and throwing a single, appropriate exception if the set is empty.

-- Chris


More information about the Python-Dev mailing list