473,320 Members | 1,719 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,320 software developers and data experts.

enumerate improvement proposal

I think that it would be handy for enumerate to behave as such:

def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step

This allows much more flexibility than in the current enumerate,
tightens up code in many cases, and seems that it would break no
existing code. Yes, I have needed this behavior with enumerate, like
tonight and the current example. I put the "step" parameter in for
conceptual symmetry with slicing.

Here is a case use (or is it use case?):
# with the proposed enumerate
import operator
def in_interval(test, bounds, first=1, reverse=False):
op = operator.gt if reverse else operator.lt # python 2.5
bounds = sorted(bounds, reverse=reverse)
for i, bound in enumerate(bounds, first):
if op(test, bound):
return i
return i + 1
# with the existing enumerate
import operator
def in_interval(test, bounds, first=1, reverse=False):
op = operator.gt if reverse else operator.lt # python 2.5
bounds = sorted(bounds, reverse=reverse)
for i, bound in enumerate(bounds):
if op(test, bound):
return i + first
return i + first + 1
py# eg
....
pyin_interval(8, bounds)
2
pyin_interval(1, bounds)
1
pyin_interval(1, bounds, reverse=True)
5
pyin_interval(8, bounds, reverse=True)
4
pyin_interval(20, bounds, reverse=True)
2

Of course, I haven't used step here. Even in this trivial example the
proposed enumerate cleans the code and logic, eliminating a couple of
plus signs. For this real-world example, the practical requirement for
reversing the bins obfuscates somewhat the de-obfuscation provided by
the proposed enumerate. But I think that it might be obvious that the
proposed enumerate could help significantly in cases a bit more
complicated than this one.

Any thoughts?

James
Oct 29 '06 #1
21 2277
James Stroud wrote:
I think that it would be handy for enumerate to behave as such:

def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step

This allows much more flexibility than in the current enumerate,
tightens up code in many cases, and seems that it would break no
existing code. Yes, I have needed this behavior with enumerate, like
tonight and the current example. I put the "step" parameter in for
conceptual symmetry with slicing.

Here is a case use (or is it use case?):
# with the proposed enumerate
import operator
def in_interval(test, bounds, first=1, reverse=False):
op = operator.gt if reverse else operator.lt # python 2.5
bounds = sorted(bounds, reverse=reverse)
for i, bound in enumerate(bounds, first):
if op(test, bound):
return i
return i + 1
# with the existing enumerate
import operator
def in_interval(test, bounds, first=1, reverse=False):
op = operator.gt if reverse else operator.lt # python 2.5
bounds = sorted(bounds, reverse=reverse)
for i, bound in enumerate(bounds):
if op(test, bound):
return i + first
return i + first + 1
py# eg
...
pyin_interval(8, bounds)
2
pyin_interval(1, bounds)
1
pyin_interval(1, bounds, reverse=True)
5
pyin_interval(8, bounds, reverse=True)
4
pyin_interval(20, bounds, reverse=True)
2

Of course, I haven't used step here. Even in this trivial example the
proposed enumerate cleans the code and logic, eliminating a couple of
plus signs. For this real-world example, the practical requirement for
reversing the bins obfuscates somewhat the de-obfuscation provided by
the proposed enumerate. But I think that it might be obvious that the
proposed enumerate could help significantly in cases a bit more
complicated than this one.

Any thoughts?

James
After a brief reflection, I realized that I just described a
"for-to-step-do" style loop one might find in many other languages, most
notably BASIC.

James
Oct 29 '06 #2
James Stroud wrote:
def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step
that's spelled

izip(count(start), sequence)

in today's Python.
def in_interval(test, bounds, first=1, reverse=False):
why is it this function's job to add an offset to the actual sequence index?

</F>

Oct 29 '06 #3
Fredrik Lundh wrote:
why is it this function's job to add an offset to the actual sequence
index?

</F>
The code is for an economist. She is insistent on starting with the
first bin as 1. I'm guessing, practically, binning linerizes data and
the bin number may potentially become a divisor or perhaps the operand
in a logarithm.

James
Oct 29 '06 #4
Fredrik Lundh wrote:
James Stroud wrote:
>def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step

that's spelled

izip(count(start), sequence)

in today's Python.
def in_interval(test, bounds, first=1, reverse=False):

why is it this function's job to add an offset to the actual sequence
index?

</F>
BTW, thank you for your tip.

James
Oct 29 '06 #5
James Stroud wrote:
The code is for an economist. She is insistent on starting with the
first bin as 1.
leaky abstractions in reverse, in other words? that's not a good design
approach.

</F>

Oct 29 '06 #6
Fredrik Lundh wrote:
James Stroud wrote:
>The code is for an economist. She is insistent on starting with the
first bin as 1.

leaky abstractions in reverse, in other words? that's not a good design
approach.

</F>
I'm not sure I understand what "leaky abstractions" means.

I am helping someone with dubious programming skills make sense of a
pile of code they wrote--code which getting a little unwieldy to debug.
I think "design approach" can't really apply here. The idea is to make
it comprehensible at some level.

I'm still curious what you mean by "leaky abstractions". Please explain.

James
Oct 29 '06 #7
James Stroud wrote:
I think that it would be handy for enumerate to behave as such:

def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step

This allows much more flexibility than in the current enumerate,
tightens up code in many cases, and seems that it would break no
existing code. Yes, I have needed this behavior with enumerate, like
tonight and the current example. I put the "step" parameter in for
conceptual symmetry with slicing.

Here is a case use (or is it use case?):
I don' think you have a use case here:

# untested
def find_interval(value, bounds, funny_offset=0, reverse=False):
bounds = sorted(bounds)
if reverse:
index = len(bounds) - bisect.bisect_left(bounds, value)
else:
index = bisect.bisect_right(bounds, value)
return index + funny_offset

You can tell by its name which of the arguments I would have omitted :-)
Of course, I haven't used step here.
That seems to be typical. The only use case I've ever come across is start=1
for output aimed at a human reader.
Even in this trivial example the
proposed enumerate cleans the code and logic, eliminating a couple of
plus signs. For this real-world example, the practical requirement for
reversing the bins obfuscates somewhat the de-obfuscation provided by
the proposed enumerate. But I think that it might be obvious that the
proposed enumerate could help significantly in cases a bit more
complicated than this one.
Of course you get these claimed advantages from a self-written function,
too.
Any thoughts?
You have my support for adding a start parameter to enumerate(). I fear it
won't make a difference.

Peter
Oct 29 '06 #8
James Stroud wrote:
I think that it would be handy for enumerate to behave as such:

def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step

This allows much more flexibility than in the current enumerate,
tightens up code in many cases, and seems that it would break no
existing code. Yes, I have needed this behavior with enumerate, like
tonight and the current example. I put the "step" parameter in for
conceptual symmetry with slicing.

Here is a case use (or is it use case?):
Incidentally, I yesterday wrote a patch giving enumerate() a start parameter
(and, more importantly, changing it so that it doesn't wraparound at
sys.maxint). It can be found here:

https://sourceforge.net/tracker/?fun...&group_id=5470

Georg
Oct 29 '06 #9
James Stroud <js*****@mbi.ucla.eduwrites:
Fredrik Lundh wrote:
why is it this function's job to add an offset to the actual
sequence index?

The code is for an economist. She is insistent on starting with the
first bin as 1.
Note that 'enumerate' is actually a built-in type, and 'enumerate()'
is the constructor returning a new object of that type.

A special case isn't special enough to change the built-in type.
>>print enumerate("ABCDE")
<enumerate object at 0xa7d642ac>
>>print list(enumerate("ABCDE"))
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E')]
>def obstinate_economist_enumerate(items):
... seq = [(i+1, x) for (i, x) in enumerate(items)]
... return iter(seq)
...
>>print obstinate_economist_enumerate("ABCDE")
<listiterator object at 0xa7d6408c>
>>print list(obstinate_economist_enumerate("ABCDE"))
[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D'), (5, 'E')]

This doesn't produce an 'enumerate' object; if you really want that,
you could subclass 'enumerate', but it seems the above function does
what you want.

--
\ "I installed a skylight in my apartment. The people who live |
`\ above me are furious!" -- Steven Wright |
_o__) |
Ben Finney

Oct 29 '06 #10
Ben Finney <bi****************@benfinney.id.auwrites:
>>print enumerate("ABCDE")
<enumerate object at 0xa7d642ac>
>>print list(enumerate("ABCDE"))
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E')]
>def obstinate_economist_enumerate(items):
... seq = [(i+1, x) for (i, x) in enumerate(items)]
... return iter(seq)
...
>>print obstinate_economist_enumerate("ABCDE")
<listiterator object at 0xa7d6408c>
>>print list(obstinate_economist_enumerate("ABCDE"))
[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D'), (5, 'E')]
An improvement: using a generator so as not to unnecessarily create an
intermediate list from the initial enumerator:
>>def obstinate_economist_enumerate(items):
... enum_iter = iter((i+1, x) for (i, x) in enumerate(items))
... return enum_iter
...
>>print obstinate_economist_enumerate("ABCDE")
<generator object at 0xa7d6444c>
>>print list(obstinate_economist_enumerate("ABCDE"))
[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D'), (5, 'E')]

--
\ "If sharing a thing in no way diminishes it, it is not rightly |
`\ owned if it is not shared." -- Saint Augustine |
_o__) |
Ben Finney

Oct 29 '06 #11
Fredrik Lundh wrote:
James Stroud wrote:
>The code is for an economist. She is insistent on starting with the
first bin as 1.


leaky abstractions in reverse, in other words? that's not a good design
approach.

</F>
Okay, I've googled "leaky abstractions" (as was probably your intended
affect with your silence), read the famous essay, and still
don't know what you mean and how it applies to what I have described.

Do you plan to justify your statement or emptily accuse people of violating
esoteric principles?

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 30 '06 #12
Ben Finney wrote:
>
>>def obstinate_economist_enumerate(items):
... enum_iter = iter((i+1, x) for (i, x) in enumerate(items))
... return enum_iter
iter is redundant here.

def natural_enumerate_improvement(items, start=0):
return ((i+start, x) for (i, x) in enumerate(items))

- Anders
Oct 30 '06 #13
Okay, I've googled "leaky abstractions" (as was probably your intended
affect with your silence), read the famous essay, and still
don't know what you mean and how it applies to what I have described.

Do you plan to justify your statement or emptily accuse people of violating
esoteric principles?
While I can't claim to know what the effbot thinks (the
skull-socks-wearing-python-coder-mindlink-technology is yet to be
developed), I think it's pretty clear what he is after here:

Computers compute offsets into data zero-based. Some languages like
pascal completely abstract that away from the user, but python doesn't.

So if your colleague/boss/whatever insists on indices being one-based,
this abstraction you introduced for her pretty fast leaks pretty badly.
Consider this simple example:

for offset, item in enumerate(some_list, start=1):
if item.is_the_chosen_one():
chosen_one_offset = offset

the_chosen_one = some_list[chosen_one_offset]

And bang, its Judas not Petrus who gets the pearly gates inc. stock options.

Diez
Oct 30 '06 #14
Diez B. Roggisch wrote:
>Okay, I've googled "leaky abstractions" (as was probably your intended
affect with your silence), read the famous essay, and still
don't know what you mean and how it applies to what I have described.

Do you plan to justify your statement or emptily accuse people of
violating
esoteric principles?


While I can't claim to know what the effbot thinks (the
skull-socks-wearing-python-coder-mindlink-technology is yet to be
developed), I think it's pretty clear what he is after here:

Computers compute offsets into data zero-based. Some languages like
pascal completely abstract that away from the user, but python doesn't.

So if your colleague/boss/whatever insists on indices being one-based,
this abstraction you introduced for her pretty fast leaks pretty badly.
Consider this simple example:

for offset, item in enumerate(some_list, start=1):
if item.is_the_chosen_one():
chosen_one_offset = offset

the_chosen_one = some_list[chosen_one_offset]

And bang, its Judas not Petrus who gets the pearly gates inc. stock
options.

Diez
Thank you for this explanation. Very illuminating. I think understand
this idea well and the thought of 1 basing this function makes me cringe
as much as the next guy (though I lacked the vocabulary to explain
exactly why I cringe).

But you see, weaning this university faculty level economist (who
already has her own way of doing everything...and to whom I happen to be
married) from the traditional economics tools of gauss and sas towards
the more sane and flexible tools of python, numarray, and rpy has been a
multi-stage process. Tweaking the chosen abstractions to not be as leaky
(thank you and thank Fredrik for introducing me to this vocabulary) is
still one of the things I'm working towards. I want to solidify the
conversion before I concentrate on nuance.

So, before too much criticism, I challenge even the most skilled python
programmer to find his or her own faculty economist (or statistician or
physicist) and get them to radically change their computational tools.
When you've walked a mile in my shoes, leaky abstractions won't seem
like such a big deal after all.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 30 '06 #15
James Stroud wrote:
Diez B. Roggisch wrote:
>>>Okay, I've googled "leaky abstractions" (as was probably your intended
affect with your silence), read the famous essay, and still
don't know what you mean and how it applies to what I have described.

Do you plan to justify your statement or emptily accuse people of
violating
esoteric principles?


While I can't claim to know what the effbot thinks (the
skull-socks-wearing-python-coder-mindlink-technology is yet to be
developed), I think it's pretty clear what he is after here:

Computers compute offsets into data zero-based. Some languages like
pascal completely abstract that away from the user, but python doesn't.

So if your colleague/boss/whatever insists on indices being one-based,
this abstraction you introduced for her pretty fast leaks pretty badly.
Consider this simple example:

for offset, item in enumerate(some_list, start=1):
if item.is_the_chosen_one():
chosen_one_offset = offset

the_chosen_one = some_list[chosen_one_offset]

And bang, its Judas not Petrus who gets the pearly gates inc. stock
options.

Diez


Thank you for this explanation. Very illuminating. I think understand
this idea well and the thought of 1 basing this function makes me cringe
as much as the next guy (though I lacked the vocabulary to explain
exactly why I cringe).

But you see, weaning this university faculty level economist (who
already has her own way of doing everything...and to whom I happen to be
married) from the traditional economics tools of gauss and sas towards
the more sane and flexible tools of python, numarray, and rpy has been a
multi-stage process. Tweaking the chosen abstractions to not be as leaky
(thank you and thank Fredrik for introducing me to this vocabulary) is
still one of the things I'm working towards. I want to solidify the
conversion before I concentrate on nuance.

So, before too much criticism, I challenge even the most skilled python
programmer to find his or her own faculty economist (or statistician or
physicist) and get them to radically change their computational tools.
When you've walked a mile in my shoes, leaky abstractions won't seem
like such a big deal after all.
Divorce is obviously the only answer. How could you end up marrying
someone who counts from one and not zero? ;-)

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 30 '06 #16
Steve Holden wrote:
How could you end up marrying
someone who counts from one and not zero? ;-)
She's the only other person I've ever met who used vi key binding at the
command line.

James
--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 31 '06 #17
* James Stroud wrote (on 10/30/2006 4:39 PM):
Steve Holden wrote:
>How could you end up marrying someone who counts from one and not
zero? ;-)

She's the only other person I've ever met who used vi key binding at the
command line.

James

Well, there's your problem. You need to C-x C-f a new mate. :)

Mark
(Emacs rules)
Oct 31 '06 #18
Mark Elston <m.******@advantest-ard.comwrites:
* James Stroud wrote (on 10/30/2006 4:39 PM):
She's the only other person I've ever met who used vi key binding
at the command line.

Well, there's your problem. You need to C-x C-f a new mate. :)
I don't have the commitment for that. What if I were to C-x C-v
a few different ones instead?

--
\ "If you continue running Windows, your system may become |
`\ unstable." -- Microsoft, Windows 95 BSOD message |
_o__) |
Ben Finney

Oct 31 '06 #19

James Stroud wrote:
Steve Holden wrote:
How could you end up marrying
someone who counts from one and not zero? ;-)

She's the only other person I've ever met who used vi key binding at the
command line.
Wow. Now I see!

It's only Python. Just add one to indices where appropriate, buy her
chocolates. Don't say a thing when you squelch your seventh off-by-one
error. Look interested in the shoe store. (even for the fifth shoe, of
the third store). - *Your partner does vi*

Whoa!

- Paddy :-)

Oct 31 '06 #20
On Mon, 30 Oct 2006 23:42:16 +0000, Steve Holden wrote:
Divorce is obviously the only answer. How could you end up marrying
someone who counts from one and not zero? ;-)

"Should array indices start at 0 or 1? My compromise of 0.5 was rejected
without, I thought, proper consideration." (Stan Kelly-Bootle)
--
Steven.

Oct 31 '06 #21
James Stroud wrote:
I think that it would be handy for enumerate to behave as such:

def enumerate(itrbl, start=0, step=1):
i = start
for it in itrbl:
yield (i, it)
i += step
I proposed something like this long ago and Guido has already rejected
it. Part of the reason is that it doesn't match his mental model of
enumerate being about pairing sequence elements with their indices.
Another reason is that the syntax has more than one obvious
interpretation:

enumerate('abcdef', 2) -- (2, 'c'), (3, 'd'), ...
enumerate('abcdef', 2) -- (0, 'c'), (1, 'd'), ...
enumerate('abcdef', 2) -- (2, 'a'), (2, 'b'), ...

Also, the order of arguments is odd in comparison with the output order
-- this suggests a syntax like enumerate(2, 'abcdef') --(2, 'a'), (3,
'b') ...

FWIW, it is not hard to roll-your-own with something like:

for pagenum, page in izip(count(1), book): ...

The izip/count combination runs at C speed, matches enumerate() in its
efficiency, and is arguably clearer in expressing its intended
behavior.
Raymond

Oct 31 '06 #22

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

Similar topics

4
by: wkaras | last post by:
I would like to propose the following changes to the C++ Standard, the goal of which are to provide an improved ability to specify the constraints on type parameters to templates. Let me say from...
40
by: Ron Adam | last post by:
After considering several alternatives and trying out a few ideas with a modified list object Bengt Richter posted, (Thank You), I think I've found a way to make slice operation (especially far end...
0
by: jygoh3 | last post by:
ENCYCLOPEDIA OF MOBILE COMPUTING & COMMERCE CALL FOR SHORT ARTICLES Proposal Deadline: 15 Nov 2005 (Extended)
47
by: Pierre Barbier de Reuille | last post by:
Please, note that I am entirely open for every points on this proposal (which I do not dare yet to call PEP). Abstract ======== This proposal suggests to add symbols into Python. Symbols...
1
by: smichr | last post by:
I see that there is a thread of a similar topic that was posted recently ( enumerate with a start index ) but thought I would start a new thread since what I am suggesting is a little different. ...
6
by: Gregory Petrosyan | last post by:
Hello! I have a question for the developer of enumerate(). Consider the following code: for x,y in coords(dots): print x, y When I want to iterate over enumerated sequence I expect this to...
2
by: eight02645999 | last post by:
hi, i am using python 2.1. Can i use the code below to simulate the enumerate() function in 2.3? If not, how to simulate in 2.1? thanks from __future__ import generators def...
8
by: Dustan | last post by:
Can I make enumerate(myObject) act differently? class A(object): def __getitem__(self, item): if item 0: return self.sequence elif item < 0: return self.sequence elif item == 0: raise...
56
by: Adem | last post by:
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" The C++ Standard (ISO/IEC 14882, Second edition, 2003-10-15) says under...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.