473,396 Members | 1,734 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

On PEP 322 (ireverse)

I've lost the original thread on my news reader so I'm opening a new
one.

First, i like the name ireverse, much better then inreverse (eek!).

Just a simple comment/question:

- Why a builtin function? Why not just stuff it in the itertools
module? The builtins is already fat as it is, making it fatter is not
the way to go, IMHO. I'd like to remeber the copy module as a case
where a fundamental protocol (__copy__ and __deepcop__) is not in the
builtins but in a standard module.

If it were to be put in itertools i'm definitely +1. On the builtins
-0 and lowering...

With my best regards,
G. Rodrigues
Jul 18 '05 #1
36 2145
Gonçalo Rodrigues wrote:
I've lost the original thread on my news reader so I'm opening a new
one.

First, i like the name ireverse, much better then inreverse (eek!).
I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!

Just a simple comment/question:

- Why a builtin function? Why not just stuff it in the itertools
It's inappropriate for itertools according to detailed criteria that
Raymond has recently posted here.
module? The builtins is already fat as it is, making it fatter is not


Yes, builtins should indeed be reserved strictly for the indispensable
cases (and trimmed a LOT in 3.0 -- but that's years away). Which is
why, e.g., list.sorted was made a classmethod of type list, rather
than a built-in. Similarly, IF iter was a type, iter.reversed would
be the "one obvious way to do it"...
Alex

Jul 18 '05 #2
> Gonçalo Rodrigues wrote:
First, i like the name ireverse, much better then inreverse (eek!).

Thanks.

[Alex] I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!


No thanks. Yuck. Please do not twist this simple idea into knots.
This is supposed to be something you can teach in the first half-hour
and then use forever. I would sooner teach negative xrange()
indices than immediately launch into dotted references to a static
method attached to something that doesn't look like it should have
a method. This is a simplification, not an exercise in being cute
or clever just to avoid a builtin.
Raymond Hettinger
Jul 18 '05 #3

"Alex Martelli" <al***@aleax.it> wrote in message
news:4x***********************@news2.tin.it...
Gonçalo Rodrigues wrote:
First, i like the name ireverse, much better then inreverse
(eek!).
I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!
As I suggested elsewhere, make iter() the type object for iterator.
Then iter.reversed is closely parallel to list.sorted.
Which is
why, e.g., list.sorted was made a classmethod of type list, rather
than a built-in. Similarly, IF iter was a type, iter.reversed would
be the "one obvious way to do it"...


Any good reason not to make iter so? int, str, and float were once
bifs also. I'm +1 on iter.reversed, along with list.sorted.

Terry J. Reedy
Jul 18 '05 #4
"Terry Reedy" <tj*****@udel.edu> wrote:
As I suggested elsewhere, make iter() the type object for iterator.
Then iter.reversed is closely parallel to list.sorted.


I've got a question about list.sorted. I assume it's just a list that's
initialized to have its elements sorted when it's created? We're not
talking about some new magic container type which keeps its elements
sorted all the time?

In other words, I'm assuming that

l = list.sorted ((1, 2, 5, 3))
l.append (4)
print l

will print [1, 2, 3, 5, 4], right?
Jul 18 '05 #5
"Terry Reedy" <tj*****@udel.edu> writes:
"Alex Martelli" <al***@aleax.it> wrote in message
news:4x***********************@news2.tin.it...
Gonçalo Rodrigues wrote:
First, i like the name ireverse, much better then inreverse

(eek!).

I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!


As I suggested elsewhere, make iter() the type object for iterator.


The what?

Cheers,
mwh

--
it's not that perl programmers are idiots, it's that the language
rewards idiotic behavior in a way that no other language or tool
has ever done -- Erik Naggum, comp.lang.lisp
Jul 18 '05 #6

"Roy Smith" <ro*@panix.com> wrote in message
news:ro***********************@reader2.panix.com.. .
"Terry Reedy" <tj*****@udel.edu> wrote:
As I suggested elsewhere, make iter() the type object for iterator. Then iter.reversed is closely parallel to list.sorted.
I've got a question about list.sorted. I assume it's just a list

that's initialized to have its elements sorted when it's created?


Correct: As I understand it,
l=list.sorted(iterable) == l=list(iterable); l.sort

tjr
Jul 18 '05 #7
[Terry Reedy]
Any good reason not to make iter so? int, str, and float were once
bifs also.
The C code for it has a split path, calling __iter__ for objects that
have it, building iterator wrappers for sequences that don't have
__iter__, or building another wrapper when the inputs are a
function and sentinel. IOW, it is a factory function capable
of constructor any of several different types.
I'm +1 on iter.reversed, along with list.sorted.


Please no.

list.sorted() is entirely unrelated. It is attached to lists because that
is what it generally returns and because its functionality is closely
tied to list.sort(). It is a class method because that gave it
richer functionality by taking any iterable as an argument:

list.sorted('a string').

When I posted the PEP for comment, I was looking for confirmation
that the underlying problem is real and for folks to look through their
own code to see if the proposed solution truly offered improvements
in terms of clarity and performance.

Grafting this onto iter is not an option; I would rather lose the
functionality than have the experts here twist it into something
I can't easily explain to a client.
Raymond Hettinger

Jul 18 '05 #8

"Raymond Hettinger" <vz******@verizon.net> wrote in message
news:YS*******************@nwrdny01.gnilink.net...
[Terry Reedy]
Any good reason not to make iter so? int, str, and float were once bifs also.
The C code for it has a split path, calling __iter__ for objects

that have it, building iterator wrappers for sequences that don't have
__iter__, or building another wrapper when the inputs are a
function and sentinel. IOW, it is a factory function capable
of constructor any of several different types.


Good reason acknowledged.
I'm +1 on iter.reversed,


rescinded.

tjr
Jul 18 '05 #9
"Raymond Hettinger" <vz******@verizon.net> writes:
[Alex]
I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!
No thanks. Yuck. Please do not twist this simple idea into knots.


[...]
This is a simplification, not an exercise in being cute
or clever just to avoid a builtin.


Agreed. Keep it simple. For a name, I'd go for ireverse() if reverse()
is not possible. But not inreverse()...

Paul
--
This signature intentionally left blank
Jul 18 '05 #10
Raymond Hettinger wrote:
When I posted the PEP for comment, I was looking for confirmation
that the underlying problem is real


well, I've never felt any need for a function that makes it impossible
to reverse a sequence...

(I think the correct form is "irreversible", by the way. I'm not sure
"irreverse" is a real word...)

</F>


Jul 18 '05 #11
Roy Smith wrote:
"Terry Reedy" <tj*****@udel.edu> wrote:
As I suggested elsewhere, make iter() the type object for iterator.
Then iter.reversed is closely parallel to list.sorted.


I've got a question about list.sorted. I assume it's just a list that's
initialized to have its elements sorted when it's created? We're not
talking about some new magic container type which keeps its elements
sorted all the time?

In other words, I'm assuming that

l = list.sorted ((1, 2, 5, 3))
l.append (4)
print l

will print [1, 2, 3, 5, 4], right?


Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
basically two obvious implementation strategies:
-- ensure the underlying list is re-sorted at each insertion,
append &c, and/or
-- let the underlying list grow as it will on insertion &c, but
make sure it's sorted at any method that accesses it (you can
use a flag -- 'have there being any append/insert/... since
the last sort?' -- to re-sort only when needed).

I'll choose the first for general use because:
-- accesses are much more frequent than modifications,
-- list.sort is VERY fast when a list is "nearly sorted"
-- the second approach would require sorting also on many
kind of changes (e.g. __setitem__ -- to ensure the items
being replaced ARE those the user expects...)
&c.

So, we clearly start with:

class alwayssortedlist(list):

def __init__(self, *args):
list.__init__(self, *args)
self.sort()

We need to ensure sorting at creation. We _might_ make the sort
method in this class a noop and call list.sort(self) instead,
but, naah -- list.sort is SO fast when called on an already
sorted list that it ain't even funny, so, choose simplicity.
Onwards to simple mods:

def append(self, *args):
list.append(self, *args)
self.sort()

def __setitem__(self, *args):
list.__setitem__(self, *args)
self.sort()

....starting to see a pattern, by any chance...?-) Yep, ALL
list mutators we _need_ to override are exactly like this!
(We MAY override e.g. index and remove to take advantage
of the sortedness, but, that's optional...:-). extend and
insert too (now, reverse IS an interesting issue...!-), and
__iadd__ and __imul__ (methods creating new lists, such as
__add__, __mul__ and __rmul__, are slightly different). Oh,
__setslice__, too.

Well, doing it in longhand is fine, of course, but why not
have a bit more fun with (not showing the __add__ &c):

class solist(list): pass

def solist_method(methname):
list_method = getattr(list, methname)
def method(self, *args):
list_method(self, *args)
self.sort()
setattr(solist, methname, method)
for n in 'init setitem iadd imul'.split:
solist_method('__%s__' % n)
for n in 'append extend insert'.split:
solist_method('%s' % n)

Not much shorter than the boilerplate/longhand, and not
perfect (we should make a new function object to give it
the right func_name -- as is, all the methods' names
will be "method" in tracebacks &c...:-), but sorta fun.

Testing & completion left as an exercise to the student...
Alex

Jul 18 '05 #12
[Alex Martelli]
Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
basically two obvious implementation strategies:
-- ensure the underlying list is re-sorted at each insertion,
append &c, and/or
-- let the underlying list grow as it will on insertion &c, but
make sure it's sorted at any method that accesses it (you can
use a flag -- 'have there being any append/insert/... since
the last sort?' -- to re-sort only when needed).

I'll choose the first for general use because:
-- accesses are much more frequent than modifications,
-- list.sort is VERY fast when a list is "nearly sorted"


That could also be an argument for the second approach.
The timsort excels at finding the unsorted part, sorting it,
and merging it with rest. And, if there were any partial
ordering of the unsorted part, it tends to take advantage
of that.

For the second approach, I would keep a sorted flag.
Whenever a new element is added the flag would be
set to False. Upon data access, a False flag indicates
a need to run sort() and then the flag is set to True.
IOW, sort only when needed and sort as many items
at a time as you can.
Raymond Hettinger

Jul 18 '05 #13
Is there any reason this PEP is of so limited scope? Why not a more
comprehensive PEP defining a reverse iteration protocol similar the
protocol we have now for forward iteration?

It just seems that if this is implemented as-is, it'll be one of those
warts left around when Python gets a reverse (or even more general)
iteration protocol that will almost certainly operate in a different
manner. It just seems to be fodder for supercession.

Jeremy
Jul 18 '05 #14
On Wed, 29 Oct 2003 20:12:23 GMT, Alex Martelli <al***@aleax.it> wrote:
Roy Smith wrote:
"Terry Reedy" <tj*****@udel.edu> wrote:
As I suggested elsewhere, make iter() the type object for iterator.
Then iter.reversed is closely parallel to list.sorted.


I've got a question about list.sorted. I assume it's just a list that's
initialized to have its elements sorted when it's created? We're not
talking about some new magic container type which keeps its elements
sorted all the time?

In other words, I'm assuming that

l = list.sorted ((1, 2, 5, 3))
l.append (4)
print l

will print [1, 2, 3, 5, 4], right?


Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
basically two obvious implementation strategies:
-- ensure the underlying list is re-sorted at each insertion,
append &c, and/or
-- let the underlying list grow as it will on insertion &c, but
make sure it's sorted at any method that accesses it (you can
use a flag -- 'have there being any append/insert/... since
the last sort?' -- to re-sort only when needed).

I'll choose the first for general use because:
-- accesses are much more frequent than modifications,
-- list.sort is VERY fast when a list is "nearly sorted"
-- the second approach would require sorting also on many
kind of changes (e.g. __setitem__ -- to ensure the items
being replaced ARE those the user expects...)
&c.

[...]

No comments on the heapq module?

Regards,
Bengt Richter
Jul 18 '05 #15
[Jeremy Fincher]
Why not a more
comprehensive PEP defining a reverse iteration protocol similar the
protocol we have now for forward iteration?


It's in there under the Custom Reverse section. The approach is so
simple it doesn't take much elaboration: Objects may define a
__ireverse__ method that returns a reverse iterator -- this allows
objects without __getitem__ and __len__ to participate in
reverse iteration.
Raymond Hettinger



Jul 18 '05 #16
Bengt Richter wrote:
...
Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
... No comments on the heapq module?


It can often offer a good _alternative_ to "a listoid container that keeps
its elements sorted" -- keeping them as a heap is cheaper than keeping them
sorted. But "if you DO want" them sorted, so that at any time accessing
mycontainer[x] gives me the x-th smallest item in mycontainer, heapq isn't
gonna be very effective.

There are many good alternatives to "keeping the elements sorted", and
heapq may well help implement some of them, but I wasn't discussing the
alternatives -- just the implementation strategies under the assumption
that the specs DO call for "always sorted".
Alex

Jul 18 '05 #17
Alex Martelli <al***@aleax.it> wrote:
class alwayssortedlist(list):

def __init__(self, *args):
list.__init__(self, *args)
self.sort()

We need to ensure sorting at creation. We _might_ make the sort
method in this class a noop and call list.sort(self) instead,
but, naah -- list.sort is SO fast when called on an already
sorted list that it ain't even funny, so, choose simplicity.
Onwards to simple mods:

def append(self, *args):
list.append(self, *args)
self.sort()

def __setitem__(self, *args):
list.__setitem__(self, *args)
self.sort()


How about this code:

a = alwaysssortedlist(range(10))
a[5] = 20

What's the use of assigning to a specific list position if the object
could end up being in some other place?

Anton

Jul 18 '05 #18
Anton Vredegoor wrote:
...
How about this code:

a = alwaysssortedlist(range(10))
a[5] = 20

What's the use of assigning to a specific list position if the object
could end up being in some other place?


For an always-sorted list, this clearly means: replace the currently
sixth-lowest item with the value 20. More generally, a[i] always
means "the (i+1)-th lowest item" -- referencing it no doubt going
to be useful much more often than replacing it, and value of i
different from the extremes (say 0, 1, -1) are going to be rare.
But, so what? One can surely imagine use cases (if one can for any
use of an "always-sorted list" rather than sorting on request).

For example: "if there is any occurrence of 20 in the list, then
replace the immediately-smaller item (if any, i.e., unless 20 is
the smallest) with another copy of the value 20". I.e.:

try: i = a.index(20)
except ValueError:
print "value 20 is not in the list"
else:
if i==0:
print "value 20 is in the list, but it's the smallest"
else:
a[i-1] = 20

I don't think I've ever needed to code this kind of thing in
production-code, but it doesn't seem particularly far-fetched
to me. Why else, except for such kinds of uses, would one want
a listoid that's _always_ sorted, rather than a cheaper heap
(see module heapq) or a list that's sorted on request...?
Alex

Jul 18 '05 #19
Alex Martelli <al***@aleax.it> writes:
For an always-sorted list, this clearly means: replace the currently
sixth-lowest item with the value 20. More generally, a[i] always
means "the (i+1)-th lowest item" -- referencing it no doubt going
to be useful much more often than replacing it, and value of i
different from the extremes (say 0, 1, -1) are going to be rare.
But, so what?


Oh, yow. Typing

a[5] = 20

and then having

a[5] != 20

is just icky. Find another notation.

Cheers,
mwh

--
The only problem with Microsoft is they just have no taste.
-- Steve Jobs, (From _Triumph of the Nerds_ PBS special)
and quoted by Aahz on comp.lang.python
Jul 18 '05 #20
|> I'm +1 on iter.reversed, along with list.sorted.

"Raymond Hettinger" <vz******@verizon.net> wrote previously:
|list.sorted() is entirely unrelated. It is attached to lists because that
|is what it generally returns and because its functionality is closely
|tied to list.sort().

Regardless of the connection to list.sorted(), I'm -1 on a built-in
'reversed()' (or whatever name).

But I'd be +1 on a function or method that lived in either the itertools
modules, or as a member of a classified iter().

There's been WAY too much pollution of the builtin namespace lately.
'reversed()' is nice enough to have not too far away, but not nearly
common enough to need as a builtin.

In fact, I find at least the following anathema in the same way:
enumerate(), sum(), zip(), xrange(). I'm probably forgetting some more.
I'd love to have these in itertools (or maybe sum() could be in math).
But teaching extra builtins is a pain... as is explaining arbitrary
distinctions between what's builtin and what's in itertools. I think if
I had my druthers, I might even put iter() in itertools.

|Grafting this onto iter is not an option; I would rather lose the
|functionality than have the experts here twist it into something
|I can't easily explain to a client.

Hmmm... that's EXACTLY the reason that I DON'T want it as a builtin.

Yours, Lulu...

--
mertz@ | The specter of free information is haunting the `Net! All the
gnosis | powers of IP- and crypto-tyranny have entered into an unholy
..cx | alliance...ideas have nothing to lose but their chains. Unite
| against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------
Jul 18 '05 #21
Alex Martelli <al***@aleax.it> wrote in message news:<Ha********************@news1.tin.it>...
Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
basically two obvious implementation strategies:
-- ensure the underlying list is re-sorted at each insertion,
append &c, and/or
-- let the underlying list grow as it will on insertion &c, but
make sure it's sorted at any method that accesses it (you can
use a flag -- 'have there being any append/insert/... since
the last sort?' -- to re-sort only when needed).

I'll choose the first for general use because:
-- accesses are much more frequent than modifications,
-- list.sort is VERY fast when a list is "nearly sorted"
-- the second approach would require sorting also on many
kind of changes (e.g. __setitem__ -- to ensure the items
being replaced ARE those the user expects...)
&c.


Any reason he shouldn't just use bisect.insort?

Jeremy
Jul 18 '05 #22
Jeremy Fincher wrote:
Alex Martelli <al***@aleax.it> wrote in message
news:<Ha********************@news1.tin.it>...
Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are
basically two obvious implementation strategies:
-- ensure the underlying list is re-sorted at each insertion,
append &c, and/or
... Any reason he shouldn't just use bisect.insort?


What about measuring the performance of the two approaches?

I've shown how incredibly simple the sort-after-whatever-addition-
or-replacement approach is -- the insort one will require some more
coding, but IF it's a lot faster, sure. But don't discount timsort's
performance -- it's often incredibly good.
Alex

Jul 18 '05 #23
Not only is it not effective, but heaps don't keep their elements in
sorted order... so if you wanted a list to stay sorted, heaps aren't
what you want. They're great for finding the smallest element
repeatedly, but not for i'th order statistics in general.
import heapq
h = [1,3,2,4]
heapq.heapify(h)
h [1, 3, 2, 4] h = [4,3,1,2]
heapq.heapify(h)
h [1, 2, 4, 3] h.sort()
h
[1, 2, 3, 4]
Alex Martelli <al***@aleax.it> wrote in message news:<ff***********************@news2.tin.it>...
Bengt Richter wrote:
...Perfectly right. If you DO want a listoid container that keeps its
elements sorted, that's not hard to make for yourself. There are

...
No comments on the heapq module?


It can often offer a good _alternative_ to "a listoid container that keeps
its elements sorted" -- keeping them as a heap is cheaper than keeping them
sorted. But "if you DO want" them sorted, so that at any time accessing
mycontainer[x] gives me the x-th smallest item in mycontainer, heapq isn't
gonna be very effective.

There are many good alternatives to "keeping the elements sorted", and
heapq may well help implement some of them, but I wasn't discussing the
alternatives -- just the implementation strategies under the assumption
that the specs DO call for "always sorted".
Alex

Jul 18 '05 #24
Ian McMeans wrote:
Not only is it not effective, but heaps don't keep their elements in
sorted order... so if you wanted a list to stay sorted, heaps aren't


Please don't "top-post": somebody reading your reply can't see what
you ARE responding to. Putting your comments AFTER the phrase you're
commenting on is much kinder to readers.

I said a heap is "not effective" (as a way to sort, in Python) because
the sort method of lists is so much faster. You CAN use a heap to
sort, it's just not an _effective_ way to perform sorting in Python.
Alex

Jul 18 '05 #25
Alex Martelli <al*****@yahoo.com> wrote in message news:<bX********************@news1.tin.it>...
Jeremy Fincher wrote:
Any reason he shouldn't just use bisect.insort?
What about measuring the performance of the two approaches?


I'll do that when I get back to my own computer. It's interesting, of
course, because although the point of bisect.insort is to use O(log n)
binary search to find the place to insert an element, it's still O(n)
because list.insert is O(n). So if timsort is close to O(n) for
nearly-sorted lists, I wonder if it would actually be faster than
bisect.insort because it's coded in C.
I've shown how incredibly simple the sort-after-whatever-addition-
or-replacement approach is -- the insort one will require some more
coding, but IF it's a lot faster, sure. But don't discount timsort's
performance -- it's often incredibly good.


If timsort is actually faster than bisect.insort in all cases, perhaps
it's time for bisect.insort to be deprecated? It's what I would
naturally use for this case because "that's what it's made for," and
it'd be unfortunate to point Python programmers to the *less*
efficient way to do something.

Jeremy
Jul 18 '05 #26
Jeremy Fincher wrote:
...
I've shown how incredibly simple the sort-after-whatever-addition-
or-replacement approach is -- the insort one will require some more
coding, but IF it's a lot faster, sure. But don't discount timsort's
performance -- it's often incredibly good.


If timsort is actually faster than bisect.insort in all cases, perhaps
it's time for bisect.insort to be deprecated? It's what I would
naturally use for this case because "that's what it's made for," and
it'd be unfortunate to point Python programmers to the *less*
efficient way to do something.


operations that modify data are a tad harder to time with timeit.py,
but not impossible with some precautions...:

[alex@lancelot bo]$ timeit.py -c -s'import bisect' -s'LL=range(99,0,3)'
'L=LL[:]'

[alex@lancelot bo]$ timeit.py -c -s'import bisect' -s'LL=range(99,0,3)'
'L=LL[:]; L.append(33); L.sort()'
100000 loops, best of 3: 2.3 usec per loop

alex@lancelot bo]$ timeit.py -c -s'import bisect' -s'LL=range(99,0,3)'
'L=LL[:]; bisect.insort(L, 33)'
100000 loops, best of 3: 4.4 usec per loop

....so, yes -- insort can't hold a candle to a list's sort method when
what you're asking them is to do the very same job. Of course,
bisect.insort_right, aka insort, has different specs -- e.g., if you
DO need to supply its lo and hi parameters, then you're considering
a very different problem from what the sort method is solving.

But yes, bisect is basically an EXAMPLE -- a working example of the
peculiarly-hard-to-code-RIGHT bisection algorithm; maybe we should
mention that in the docs. Lemme see if I can borrow the time machine
for the purpose... done. Now, the docs do clearly say:

"""
The source code may be most useful as a working example of the algorithm
"""

Better, hm?-)
Alex

Jul 18 '05 #27
In article <Jf*******************@nwrdny02.gnilink.net>,
Raymond Hettinger <py****@rcn.com> wrote:

No thanks. Yuck. Please do not twist this simple idea into knots.
This is supposed to be something you can teach in the first half-hour
and then use forever. I would sooner teach negative xrange()
indices than immediately launch into dotted references to a static
method attached to something that doesn't look like it should have
a method. This is a simplification, not an exercise in being cute
or clever just to avoid a builtin.


Counter-yuck. ;-) I just can't see reverse() by any name being one of
the first things taught about Python.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan
Jul 18 '05 #28
In article <4x***********************@news2.tin.it>,
Alex Martelli <al***@aleax.it> wrote:

I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!


Raymond has vetoed this, but I don't understand why iter() needs to grow
a staticmethod. After all, it's just a function that can be decorated
with attributes....
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan
Jul 18 '05 #29
Aahz wrote:
In article <4x***********************@news2.tin.it>,
Alex Martelli <al***@aleax.it> wrote:

I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!


Raymond has vetoed this, but I don't understand why iter() needs to grow
a staticmethod. After all, it's just a function that can be decorated
with attributes....


built-in functions normally can't, and in that way they differ from
C-coded functions. So, iter would have to be changed into a different
type that _does_ support some attributes.
Alex

Jul 18 '05 #30
In article <gD********************@news1.tin.it>,
Alex Martelli <al***@aleax.it> wrote:
Aahz wrote:
In article <4x***********************@news2.tin.it>,
Alex Martelli <al***@aleax.it> wrote:

I still prefer Werner Schiendl's idea of iter.reversed, IF we find a
way to have builtin function iter grow a 'staticmethod' of sorts...!


Raymond has vetoed this, but I don't understand why iter() needs to grow
a staticmethod. After all, it's just a function that can be decorated
with attributes....


built-in functions normally can't, and in that way they differ from
C-coded functions. So, iter would have to be changed into a different
type that _does_ support some attributes.


Did you mean "Python-coded"? Anyway, I doubt that adding an attribute
to iter() would cause problems the way changing it to a type constructor
would. I'm not suggesting this, mind, just curious why nobody else
mentioned the possibility.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan
Jul 18 '05 #31
Aahz wrote:
...
built-in functions normally can't, and in that way they differ from
C-coded functions. So, iter would have to be changed into a different
type that _does_ support some attributes.
Did you mean "Python-coded"? Anyway, I doubt that adding an attribute


Yep.
to iter() would cause problems the way changing it to a type constructor
would. I'm not suggesting this, mind, just curious why nobody else
mentioned the possibility.


I think one needs *more* work to add an attribute to a C-coded function:
it needs to be made into a different type. To add a classmethod to a type
one only needs to supply the classmethod flag in one's C sources -- hard
to see how that might be more troublesome...?
Alex

Jul 18 '05 #32
In article <VH********************@news1.tin.it>,
Alex Martelli <al*****@yahoo.com> wrote:

I think one needs *more* work to add an attribute to a C-coded function:
it needs to be made into a different type. To add a classmethod to a type
one only needs to supply the classmethod flag in one's C sources -- hard
to see how that might be more troublesome...?


Someone claimed that making iter() a type constructor would not be
backward-compatible. This certainly would be.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan
Jul 18 '05 #33
Aahz wrote:
In article <VH********************@news1.tin.it>,
Alex Martelli <al*****@yahoo.com> wrote:

I think one needs *more* work to add an attribute to a C-coded function:
it needs to be made into a different type. To add a classmethod to a type
one only needs to supply the classmethod flag in one's C sources -- hard
to see how that might be more troublesome...?


Someone claimed that making iter() a type constructor would not be
backward-compatible. This certainly would be.


Only if we propagated the [expletive deleted] hack whereby, these days,
int(...) is NOT guaranteed something that's an instance of int. We do
need that hack as a prop on the way to int/long unification, I guess
(sigh), but getting MORE such cases is an icky prospect.

If type iter is an abstract baseclass, calling iter should fail -- that
is what calling basestring does, for example, and AFAIK it's the only
precedent in Python, but it's the common meaning of abstract baseclasses.

If type iter is instantiable, right after "x=iter(...)" I'd really
want to be able to "assert type(x) is iter" -- and of course I can't.

I can't even assert the weaker isinstance(x, iter), not in a backwards
compatible manner, since e.g. iter(x) will gladly return x any time x
is an iterator (def __iter__(self): return self), and iterators need not
subclass a hypothetical type iter.

So, "makint iter() a type constructor" while remaining backwards
compatible would mean "makint iter() a type constructor which hardly
ever returns an instance of iter" -- barf.

Nope -- even though I'd STILL like "iter.reversed", we can't make
iter a type, backwards compatibly, in a DECENT way; we'd really need
a new subtype of "builtin function" which can have attributes.
Alex

Jul 18 '05 #34
In article <xx********************@news1.tin.it>, Alex Martelli wrote:

Nope -- even though I'd STILL like "iter.reversed", we can't make
iter a type, backwards compatibly, in a DECENT way; we'd really need
a new subtype of "builtin function" which can have attributes.


Pardon me for missing this, but what was the rationale for not just calling
it "reverse" and putting it in builtins? And likewise for "sort"?

--
..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
Jul 18 '05 #35
On Mon, 03 Nov 2003 05:01:10 +0000, Dave Benjamin wrote:
Pardon me for missing this, but what was the rationale for not just calling
it "reverse" and putting it in builtins? And likewise for "sort"?


reverse and sort already exist in Python, as list methods.

L.reverse() reverses, in-place, the items of list L.
L.sort([f]) Sorts, in-place, the items of L, comparing items by f;
if f is ommitted, cmp is used as comparison function.
(pg 49, _Python in a Nutshell_)

Anna
Jul 18 '05 #36
Anna wrote:
On Mon, 03 Nov 2003 05:01:10 +0000, Dave Benjamin wrote:
Pardon me for missing this, but what was the rationale for not just
calling it "reverse" and putting it in builtins? And likewise for "sort"?


reverse and sort already exist in Python, as list methods.

L.reverse() reverses, in-place, the items of list L.
L.sort([f]) Sorts, in-place, the items of L, comparing items by f;
if f is ommitted, cmp is used as comparison function.
(pg 49, _Python in a Nutshell_)


Yes, the risk of confusion between the existing list methods and the
new functions does play a role in wanting to differentiate their names.

As to whether the new functions (by whatever names) must become
built-ins, that's a separate controversy. Raymond is keen to have
them as built-ins because he views them as "fundamental looping
constructs". Guido has decided that list.sorted will be a
classmethod of list instead (more general, one less built-in),
but has essentially approved some reverse-iterating function as a
built-in (and Raymond has vetoed having it as _anything BUT_ a
built-in) so the only issue where debate is allowed (at least
according to Raymond) is on the exact name -- almost.

Almost, because one alternative may still be open: having a
"reversed range" iterator. I think a built-in 'irange' with an
option to reverse would end up as more generally useful than a
"reverse iterator". But if the choice is only between either
the reverse iterator, or a revrange iterator builtin, I would
be roughly neutral -- having _three_ built-ins for arithmetic
progressions, with range returning a list, xrange a "neither
fish nor fowl" ``almost but not quite a list // almost but not
quite an iterator'', revrange an iterator, is just too messy to
feel comfortable. If we introduced a general irange instead
we'd be ready to deprecate xrange soon, _and_ eventually change
range into a simple list(irange(... -- ah BLISS. Therefore,
to me, introducing irange sounds like a general, clean, wise,
far-seeing approach, while revrange feels too specialized to
"pull its weight" as a built-in. Oh well.
Alex

Jul 18 '05 #37

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

35
by: Raymond Hettinger | last post by:
Here is a discussion draft of a potential PEP. The ideas grew out of the discussion on pep-284. Comments are invited. Dart throwing is optional. Raymond Hettinger ...
59
by: Raymond Hettinger | last post by:
Please comment on the new PEP for reverse iteration methods. Basically, the idea looks like this: for i in xrange(10).iter_backwards(): # 9,8,7,6,5,4,3,2,1,0 <do something with i> The...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.