[Python-Dev] Retrieve an arbitrary element from a setwithoutremoving it

Raymond Hettinger python at rcn.com
Fri Oct 30 05:00:27 CET 2009


[Steven D'Aprano]
> The suggested
> semantics for set.get() with no arguments, as I understand them, are:
>
>(1) it will only fail if the set is empty;

Just like next() except that next() gives you the option to supply a default
and can be used on any iterator (perhaps iter(s) or itertools.cycle(s) etc).


> (2) it should be efficient;

Is this about optimization?

I wouldn't expect "x=s.get()" to beat "for x in s: break".
Attribute lookup and method calls usually are slower
than equivalents using built-in syntax with specific opcodes.


> (3) if you call it repeatedly on a set without modifying the set, you
> will cycle through each element in turn in some unspecified arbitrary
> order.

What's wrong with using next()?  That is what it's for.

What about this proposal is specific to sets, i.e. why don't you want the same thing for lists. tuples, strings, file objects, or 
any other iterable?

Does this proposal pass the test of being self-descriptive?  Can you write a code fragment that exercises the cycling behavior, show 
it to another programmer, and have them correctly deduce what the code does (i.e. that different values are returned, that it fails 
when the set it empty, that it wraps around and never terminates)?  Can they readily differentiate it for dict.get() which has 
decidedly different semantics?



> To clarify point 3, given:
>
> x = set.get()
> y = set.get()
>
> then x and y will only be the same element if set has length one.

So, it can't even be used for looping through a set because there is no termination?



> I believe that the patch supplied by Willi Richart implemented these
> behaviours.
>
> http://bugs.python.org/issue7212

So you want to introduce additional, hidden state to sets? (to make sure that successive invocations return different values)

Do you want a thread local version too? (so that two threads can call gets without stomping on each other's guarantees that 
successive calls will produce distinct elements)

Do you have any real-world use-cases where next(), for-loops, or itertools wouldn't suffice?

Is there a precedent in *any* other language you've ever seen?  (setl has an "arb" function but it makes no promises about returning 
different values on consequetive calls; otherwise, I've never seen an equivalent in any other set implementation).

Do you think the return-different-values-on-successive-calls semantics is self-evident and non-magical as compared to a straight 
for-loop or next(it)?

ISTM, that when streams have non-destructive getters with self-advancing pointers, they also have a seek() function so that it can 
be controlled.  Will this proposal need a seek() method too?

Sorry for so many questions, but I honestly think there are too many unresolved design issues.  We've seen no real-world source code 
that would be improved fwith the proposal.  I think it sounds conceptually tempting and is fun to theorize about, but it actual 
implementation it will make sets more difficult to learn and it would quickly become a piece of rarely used, poorly understood 
cruft.


Raymond



More information about the Python-Dev mailing list