Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Dev

Re: Retrieve an arbitrary element from a set withoutremoving it

 

 

First page Previous page 1 2 3 Next page Last page  View All Python dev RSS feed   Index | Next | Previous | View Threaded


python at rcn

Oct 26, 2009, 12:23 PM

Post #1 of 52 (1958 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it

Chris Bergstresser]
> I like the proposed set.get() method, personally.

Sets have been implemented in many languages, but I've only
seen one that implemented this functionality (the "arb" function
in SETL). For the most part, it seems that this is an uncommon need.

Also consider that there is value to keeping the set-api as
simple as possible. Right now, anyone who was exposed
to the basics of sets in school can understand the set-api
with a near zero learning curve. Some of that would be
lost if you add methods that make identity/equality distinctions
or that fetch the same arbitrary value over and over again.

Besides, it is trivial to write a short function that encapsulates
this behavior if it is part of your personal style of expression.



> 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 ...

A short comment would do wonders.


Raymond


P.S. It is weird that this thread is gaining traction at the same
time as the moratorium thread. Go figure :-)
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


guido at python

Oct 26, 2009, 12:56 PM

Post #2 of 52 (1912 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Mon, Oct 26, 2009 at 12:23 PM, Raymond Hettinger <python [at] rcn> wrote:
> P.S.  It is weird that this thread is gaining traction at the same
> time as the moratorium thread.  Go figure :-)

I'm beginning to think maybe adding a method to a built-in object type
*should* fall under the moratorium.

--
--Guido van Rossum

PS. My elbow needs a couple more weeks of rest. Limiting myself to
ultra-short emails.
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


jnoller at gmail

Oct 26, 2009, 1:06 PM

Post #3 of 52 (1912 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Mon, Oct 26, 2009 at 3:56 PM, Guido van Rossum <guido [at] python> wrote:
> On Mon, Oct 26, 2009 at 12:23 PM, Raymond Hettinger <python [at] rcn> wrote:
>> P.S.  It is weird that this thread is gaining traction at the same
>> time as the moratorium thread.  Go figure :-)
>
> I'm beginning to think maybe adding a method to a built-in object type
> *should* fall under the moratorium.

So far, fiddling with the PEP, I'm on the fence - adding a method to a
built-in object type is sort of a grey area (at least in my mind). It
depends on if doing so significantly alters the language/syntax.

jesse
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


debatem1 at gmail

Oct 26, 2009, 1:14 PM

Post #4 of 52 (1914 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Mon, Oct 26, 2009 at 3:56 PM, Guido van Rossum <guido [at] python> wrote:
> On Mon, Oct 26, 2009 at 12:23 PM, Raymond Hettinger <python [at] rcn> wrote:
>> P.S.  It is weird that this thread is gaining traction at the same
>> time as the moratorium thread.  Go figure :-)
>
> I'm beginning to think maybe adding a method to a built-in object type
> *should* fall under the moratorium.
>
> --
> --Guido van Rossum

Seems like any changes requiring support from uninvolved
developers should fall under the moratorium. If the proposal
is to add a set.get() function to the set API, then this clearly
falls under that heading.

Geremy Condra
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


dickinsm at gmail

Oct 26, 2009, 1:26 PM

Post #5 of 52 (1923 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Mon, Oct 26, 2009 at 7:56 PM, Guido van Rossum <guido [at] python> wrote:
> I'm beginning to think maybe adding a method to a built-in object type
> *should* fall under the moratorium.

Another possible test case for this decision is the int.from_bytes and
int.to_bytes methods, proposed a while ago, and implemented
by Alexandre Vassalotti. See:

http://bugs.python.org/issue1023290

Mark
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


w.richert at gmx

Oct 26, 2009, 2:14 PM

Post #6 of 52 (1914 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

For those of you who want to tinker with it, I posted the patch against the
current trunk at http://bugs.python.org/issue7212

Have fun,
wr

Am Montag, 26. Oktober 2009 21:32:32 schrieb Guido van Rossum:
> On Mon, Oct 26, 2009 at 1:19 PM, Antoine Pitrou <solipsis [at] pitrou> wrote:
> > Jesse Noller <jnoller <at> gmail.com> writes:
> >> So far, fiddling with the PEP, I'm on the fence - adding a method to a
> >> built-in object type is sort of a grey area (at least in my mind). It
> >> depends on if doing so significantly alters the language/syntax.
> >
> > We have recently added things like float.fromhex() which IMHO shouldn't
> > be blocked by the moratorium (*), although they technically add a method
> > to a built-in.
> >
> > (*) it is a minor new feature aimed at catching up with some established
> > standard for an exact, non-ambiguous string representation of floats
>
> Okay, so it remains a gray area.
>
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


python at rcn

Oct 27, 2009, 10:47 AM

Post #7 of 52 (1887 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

[Chris Bergstresser]
Still, I think my
> point stands--it's a clear extrapolation from the existing dict.get().

Not really. One looks-up a key and supplies a default value if not found.
The other, set.get(), doesn't have a key to lookup.

A dict.get() can be meaningfully used in a loop (because the key can vary).
A set.get() returns the same value over and over again (because there is no key).


Raymond
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


solipsis at pitrou

Oct 27, 2009, 10:59 AM

Post #8 of 52 (1885 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

Raymond Hettinger <python <at> rcn.com> writes:
>
> [Chris Bergstresser]
> Still, I think my
> > point stands--it's a clear extrapolation from the existing dict.get().
>
> Not really. One looks-up a key and supplies a default value if not found.
> The other, set.get(), doesn't have a key to lookup.

set.getone() then ?



_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


debatem1 at gmail

Oct 27, 2009, 11:20 AM

Post #9 of 52 (1886 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Tue, Oct 27, 2009 at 1:59 PM, Antoine Pitrou <solipsis [at] pitrou> wrote:
> Raymond Hettinger <python <at> rcn.com> writes:
>>
>> [Chris Bergstresser]
>>   Still, I think my
>> > point stands--it's a clear extrapolation from the existing dict.get().
>>
>> Not really.  One looks-up a key and supplies a default value if not found.
>> The other, set.get(), doesn't have a key to lookup.
>
> set.getone() then ?

ugh- other spellings much preferred.

Geremy Condra
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


tjreedy at udel

Oct 27, 2009, 11:50 AM

Post #10 of 52 (1889 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

Raymond Hettinger wrote:
>
> A dict.get() can be meaningfully used in a loop (because the key can vary).
> A set.get() returns the same value over and over again (because there is
> no key).

There are two ideas of set.get floating about:
1) get an arbitrary object
2) get the object in the set with the same 'value'(hash+eq) as an input
arg (the intern case). In this case, there is a 'key', even if it is
somewhat abstract rather that being an object.

Both could be done with the same method, depending on whether an arg is
passed or not. The former is not useful in a loop; the latter could be.

If there is no match in case 2, the method could a) raise an exception,
b) return None (which by its nature would never sensibly be looked up),
or c) return an object specified by 'default=xxx' keyword arg.

Terry Jan Reedy

_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


chris at subtlety

Oct 27, 2009, 12:02 PM

Post #11 of 52 (1889 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Tue, Oct 27, 2009 at 12:47 PM, Raymond Hettinger <python [at] rcn> wrote:
> [Chris Bergstresser]
>  Still, I think my
>>
>> point stands--it's a clear extrapolation from the existing dict.get().
>
> Not really.  One looks-up a key and supplies a default value if not found.
> The other, set.get(), doesn't have a key to lookup.

Right, which is why dict.get() takes a key as an argument, while
the proposed set.get() wouldn't.

> A dict.get() can be meaningfully used in a loop (because the key can vary).
> A set.get() returns the same value over and over again (because there is no
> key).

I don't think "can it be used meaningfully in a loop?" is an
especially interesting or useful way of evaluating language features.
Besides, why would set.get() necessarily return the same value
over and over again? I thought it would be defined to return an
arbitrary value--which could be the same value over and over again,
but could just as easily be defined to return a round-robin value, or
the minimum value, or some *other* value as the container defined it.
The fact is, set.get() succinctly describes an action which is
otherwise obscure in Python. It doesn't come up all that frequently,
but when it does the alternatives are poor at best. Add in the
uncertainty about which is optimized (imagine the situation where the
set you're calling is actually a proxy for an object across the
network, and constructing an iterator is expensive) and you start to
see the value.

-- Chris
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ssteinerx at gmail

Oct 27, 2009, 12:06 PM

Post #12 of 52 (1885 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Oct 27, 2009, at 2:50 PM, Terry Reedy wrote more and more and more
and more and more and more and more and more and more:

This topic needs its own flippin' newsgroup.

S

_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


guido at python

Oct 27, 2009, 12:13 PM

Post #13 of 52 (1896 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Tue, Oct 27, 2009 at 11:50 AM, Terry Reedy <tjreedy [at] udel> wrote:
> There are two ideas of set.get floating about:
> 1) get an arbitrary object
> 2) get the object in the set with the same 'value'(hash+eq) as an input arg
> (the intern case). In this case, there is a 'key', even if it is somewhat
> abstract rather that being an object.
>
> Both could be done with the same method, depending on whether an arg is
> passed or not.

My gut tells me it is bad API design to collapse these two use cases.
Probably because the implementations won't have much in common: (1)
should just pick the first valid element, while (2) should use the
normal hash lookup algorithm (shared with 'in', .add() etc.).

--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


jnoller at gmail

Oct 27, 2009, 12:13 PM

Post #14 of 52 (1884 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Tue, Oct 27, 2009 at 3:06 PM, ssteinerX [at] gmail
<ssteinerx [at] gmail> wrote:
>
> On Oct 27, 2009, at 2:50 PM, Terry Reedy wrote more and more and more and
> more and more and more and more and more and more:
>
> This topic needs its own flippin' newsgroup.
>
> S

Don't like it? Mute the conversation (thank you gmail) or unsub.
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


debatem1 at gmail

Oct 27, 2009, 12:27 PM

Post #15 of 52 (1889 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Tue, Oct 27, 2009 at 3:13 PM, Guido van Rossum <guido [at] python> wrote:
> On Tue, Oct 27, 2009 at 11:50 AM, Terry Reedy <tjreedy [at] udel> wrote:
>> There are two ideas of set.get floating about:
>> 1) get an arbitrary object
>> 2) get the object in the set with the same 'value'(hash+eq) as an input arg
>> (the intern case). In this case, there is a 'key', even if it is somewhat
>> abstract rather that being an object.
>>
>> Both could be done with the same method, depending on whether an arg is
>> passed or not.
>
> My gut tells me it is bad API design to collapse these two use cases.
> Probably because the implementations won't have much in common: (1)
> should just pick the first valid element, while (2) should use the
> normal hash lookup algorithm (shared with 'in', .add() etc.).
>
> --
> --Guido van Rossum (python.org/~guido)


Was it ever decided whether this would fall under the moratorium?

Geremy Condra
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


tjreedy at udel

Oct 27, 2009, 8:02 PM

Post #16 of 52 (1876 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

ssteinerX [at] gmail wrote:
>
> On Oct 27, 2009, at 2:50 PM, Terry Reedy wrote more and more and more
> and more and more and more and more and more and more:

Actually, I wrote 7 succinct lines that summarized and made a proposal.
In general, I snip when quoting and write concisely as possible.

> This topic needs its own flippin' newsgroup.

You need to learn politeness. You could have said just that, appropriate
or not, without dumping on anyone in particular.

Terry Jan Reedy


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ssteinerx at gmail

Oct 27, 2009, 8:27 PM

Post #17 of 52 (1872 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Oct 27, 2009, at 11:02 PM, Terry Reedy wrote:

> ssteinerX [at] gmail wrote:

> This topic needs its own flippin' newsgroup.
> You could have said just that, appropriate or not, without dumping
> on anyone in particular.

I was not trying to dump on you in particular, I picked a random
message of the trillions that went by and happened to get you. I
apologize if you felt dumped on.

No offense intended to you in particular but this thread has gone on
and on and on and on and on and on...

S

_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


steve at pearwood

Oct 29, 2009, 7:58 PM

Post #18 of 52 (1833 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Wed, 28 Oct 2009 04:47:59 am Raymond Hettinger wrote:

> A dict.get() can be meaningfully used in a loop (because the key can
> vary). A set.get() returns the same value over and over again
> (because there is no key).

I don't believe anyone has requested those semantics. The suggested
semantics for set.get() with no arguments, as I understand them, are:

(1) it will only fail if the set is empty;

(2) it should be efficient;

(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.

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.
However, given:

x = set.get()
set.add(el)
set.remove(el)
y = set.get()

there are no guarantees about x and y being different.

I believe that the patch supplied by Willi Richart implemented these
behaviours.

http://bugs.python.org/issue7212



--
Steven D'Aprano
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


python at rcn

Oct 29, 2009, 9:00 PM

Post #19 of 52 (1827 views)
Permalink
Re: Retrieve an arbitrary element from a setwithoutremoving it [In reply to]

[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

_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


w.richert at gmx

Oct 30, 2009, 1:16 AM

Post #20 of 52 (1832 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

Am Freitag, 30. Oktober 2009 03:58:16 schrieb Steven D'Aprano:
> 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.
> However, given:
>
> x = set.get()
> set.add(el)
> set.remove(el)
> y = set.get()
>
> there are no guarantees about x and y being different.
>
> I believe that the patch supplied by Willi Richart implemented these
> behaviours.
>
> http://bugs.python.org/issue7212
>


Actually, no. The patch makes no assumption about x and y being different.

It does not try to extend the core functionality of set nor does it need to
maintain any state that would be necessary for that.

It is just a more obvious and cleaner way for saying "for x in some_set:
break". So, as Raymond says, it is the Pythonic version of "arb" in setl.


wr
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


steve at pearwood

Oct 30, 2009, 8:11 AM

Post #21 of 52 (1819 views)
Permalink
Re: Retrieve an arbitrary element from a setwithoutremoving it [In reply to]

On Fri, 30 Oct 2009 03:00:27 pm Raymond Hettinger wrote:

[skipping to the last paragraph]

> Sorry for so many questions

Don't be sorry. These are good questions, and I'll try to answer them.
But keep in mind that this isn't my proposal -- I vary between +0 and
+1 on the proposal depending on the time of the day *wink*


> >(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).

Yes. I had considered suggesting that sets become their own iterator, so
you could do the following:

>>> s = set([1,2])
>>> next(s)
2

but that leads to the problem that if you accept a set from somewhere
else, you have no idea whether next(s) will succeed or raise
StopIteration. It may have already been exhausted before it reached
you.


> > (2) it should be efficient;
>
> Is this about optimization?

Not primarily. Perhaps I should have said it should not be inefficient.
It's primarily about there being One Obvious Way to extract an
arbitrary item from a set -- this is a reoccurring question on
comp.lang.python. Being efficient is a bonus, but it shouldn't be
inefficient.


> 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.

Obviously any hypothetical solution would need to be benchmarked, but I
wouldn't be concerned if s.get() was marginally slower than for `x in
s: break`.

When people are left to come up with their own ad hoc solutions, we've
seen some poor solutions. I've seen, possibly in this very thread, the
following O(N) suggestions:

for x in s:
pass

x = list(s)[0]

The usual technique people tend to come up with is:

x = s.pop()
s.add(x)

Which strikes many people (including myself) as inelegant. Surely "get
an element" is a more fundamental operation than "get an element and
remove it"?


> > (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.

You can't call next() on a set. You have to call next(iter(set)). From
Python 3.0:

>>> next(set([1,2]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: set object is not an iterator
>>> next(iter(set([1,2])))
1

Unless I missed something, this is so unobvious that nobody has
suggested it in the thread yet.


> 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?

Sequences such as lists, tuples and strings have easy random access.
It's easy to get an arbitrary element: pick an index i by whatever
method you like, and get seq[i]. Many file objects are similar, you
have random access with seek().

It is unpractical and an over-generalisation to apply this to general
iterables, for reasons I'm sure I don't need to go into. But sets and
frozensets aren't lazily generated streams, they actually do store the
elements inside their data structure in the same way that lists do.


> 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?

I don't expect ConfigParser.get() to have the same semantics as
dict.get(), and they're much more closely related than sets and dicts.
I don't understand why so many people apparently have a problem with
the name get(), but that's okay, I'm not wedded to the idea either. If
folks prefer a different name, by all means suggest it. I like the name
suggested by Wikipedia, "pick".

As for being self-descriptive, I don't know, I haven't tried the
experiment.


> > 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?

That's a feature, not a bug! This is not intended to be a replacement
for standard set iteration. Anyone writing the following:

for _ in len(s):
process(s.get())

instead of

for x in s:
process(x)

will be taken out and slapped with a large fish.

My reasoning for the given behaviour is as follows:

* If you want the same element twice from a set, the One Obvious Way is
to get an element from the set (somehow!) and assign it to a local
variable:

x = s.get()
process(x)
# later...
process(x)

So having get() return the same value each time is not useful or
necessary.

* If you want a random element on each call, the One Obvious Way is to
call random.choice(list(s)).

* Since sets aren't mappings, or sequences, there's no sensible way to
look up an index or key, so any variation of "get element #1" are out.

* Which leaves returning the elements in some unspecified arbitrary
order. The most obvious arbitrary order is to cycle through them, which
conveniently is exactly what iter(set) does, but we don't need to
guarantee that order.


> > 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)

If you can think of any other way to efficiently cycle over the elements
in a set, I'm all for it :)

Presumably this is no different from what dict views do, except they
don't wrap around when exhausted.


> 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)

I think that's overkill. I wouldn't think we need to guarantee that two
threads don't see the same element, or that each thread will see each
element in the same order. We need only the much weaker guarantee that
two subsequent calls to get() in the one thread with no modification to
the set between the calls won't retrieve the same element each time
(unless there is only one element to retrieve), and that each element
will eventually be seen.


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

Someone in this thread -- forgive me, I don't recall who -- had the case
where they had a frozenset which they knew only had one element, but no
obvious way to retrieve that element.

To my mind, the major rationalisation for set.get() is not that there's
no way to get a single element from a set, but that there is no
obvious, easily discoverable way to retrieve a single element.


> 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).

I can't say I've seen one in any other languages, but Wikipedia
lists "pick" as a fundamental set operation:

pick(S): returns an arbitrary element of S.

http://en.wikipedia.org/wiki/Set_(computer_science)



This page claims that Icon has an operator that returns a random element
of a set:

? set( [1, 2, 3, 4, 5] )

http://stackoverflow.com/questions/124671/picking-a-random-element-from-a-set

but I've never used Icon myself and so can't confirm that.



> 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)?

I'm going to sit on the fence on that and say "maybe".


> 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?

No. Since sets are unordered, there's no way to seek to a specific
element.


> 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.



--
Steven D'Aprano
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


solipsis at pitrou

Oct 30, 2009, 8:35 AM

Post #22 of 52 (1809 views)
Permalink
Re: Retrieve an arbitrary element from a set without removing it [In reply to]

Steven D'Aprano <steve <at> pearwood.info> writes:
>
> If you can think of any other way to efficiently cycle over the elements
> in a set, I'm all for it :)

How about "for x in s"?

Or if you want to cycle:

>>> s = set('abc')
>>> it = itertools.cycle(s)
>>> next(it)
'a'
>>> next(it)
'c'
>>> next(it)
'b'
>>> next(it)
'a'

Or if you don't want the overhead of itertools.cycle() keeping a copy of the
set's elements:

>>> s = set('abc')
>>> it = itertools.chain.from_iterable(itertools.cycle([s]))
>>> next(it)
'a'
>>> next(it)
'c'
>>> next(it)
'b'
>>> next(it)
'a'
>>> next(it)
'c'
>>> next(it)
'b'

> I can't say I've seen one in any other languages, but Wikipedia
> lists "pick" as a fundamental set operation:
>
> pick(S): returns an arbitrary element of S.

Well, it's an arbitrary element. It isn't specified that it will try to return
different results in a row to satisfy the developer's aesthetical preferences...

> This page claims that Icon has an operator that returns a random element
> of a set:
>
> ? set( [1, 2, 3, 4, 5] )

random != arbitrary != weak-guaranteedly distinct


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ncoghlan at gmail

Oct 30, 2009, 8:46 AM

Post #23 of 52 (1807 views)
Permalink
Re: Retrieve an arbitrary element from a setwithoutremoving it [In reply to]

Steven D'Aprano wrote:
>> So you want to introduce additional, hidden state to sets? (to make
>> sure that successive invocations return different values)
>
> If you can think of any other way to efficiently cycle over the elements
> in a set, I'm all for it :)

for x in itertools.cycle(s):
# this is an infinite loop

Having a pick() or get() method that returns an arbitrary member of a
set makes sense to me. Having any state on the set that guarantees
successive calls to get will return different values feels wrong -
creating an object with that extra state is what iter(s) is for.

Cheers,
Nick.

--
Nick Coghlan | ncoghlan [at] gmail | Brisbane, Australia
---------------------------------------------------------------
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


amk at amk

Oct 30, 2009, 1:27 PM

Post #24 of 52 (1798 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

On Fri, Oct 30, 2009 at 09:37:36PM +0100, Georg Brandl wrote:
> I don't like this. It gives a set object a hidden state, something that
> AFAICS no other builtin has. Iterating over an iterable is what iterators
> are for.

It also makes the object thread-unsafe; there's no way for two threads
to iterate over it at the same time. It's a terrible idea to
introduce new things that won't work under threaded usage.

--amk
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


g.brandl at gmx

Oct 30, 2009, 1:37 PM

Post #25 of 52 (1810 views)
Permalink
Re: Retrieve an arbitrary element from a set withoutremoving it [In reply to]

Steven D'Aprano schrieb:
> On Wed, 28 Oct 2009 04:47:59 am Raymond Hettinger wrote:
>
>> A dict.get() can be meaningfully used in a loop (because the key can
>> vary). A set.get() returns the same value over and over again
>> (because there is no key).
>
> I don't believe anyone has requested those semantics. The suggested
> semantics for set.get() with no arguments, as I understand them, are:
>
> (1) it will only fail if the set is empty;
>
> (2) it should be efficient;
>
> (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.

I don't like this. It gives a set object a hidden state, something that
AFAICS no other builtin has. Iterating over an iterable is what iterators
are for.

Georg

--
Thus spake the Lord: Thou shalt indent with four spaces. No more, no less.
Four shall be the number of spaces thou shalt indent, and the number of thy
indenting shall be four. Eight shalt thou not indent, nor either indent thou
two, excepting that thou then proceed to four. Tabs are right out.

_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com

First page Previous page 1 2 3 Next page Last page  View All Python dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.