Is it possible to write a list comprehension for this so as to produce a
list of two-item tuples?
base_scores = range(8, 19)
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
print zip(base_scores, score_costs)
I can't think of how the structure of the list comprehension would work
in this case, because it seems to require iteration over two separate
sequences to produce each item in the tuple.
zip seems to work fine anyway, but my immediate instinct was to try a
list comprehension (until I couldn't figure out how!). And I wasn't sure
if list comps were capable of doing everything a zip could do.
Thanks. 33 1672
On Jun 5, 10:42�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Is it possible to write a list comprehension for this so as to produce a
list of two-item tuples?
base_scores = range(8, 19)
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
print zip(base_scores, score_costs)
I can't think of how the structure of the list comprehension would work
in this case, because it seems to require iteration over two separate
sequences to produce each item in the tuple.
zip seems to work fine anyway, but my immediate instinct was to try a
list comprehension (until I couldn't figure out how!). And I wasn't sure
if list comps were capable of doing everything a zip could do.
Thanks.
base_scores = range(8, 19)
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
print zip(base_scores, score_costs)
s = [(i+8,j) for i,j in enumerate( [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3])]
print s
##>>>
##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
2), (16, 2), (17, 3), (18, 3)]
##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
2), (16, 2), (17, 3), (18, 3)]
##>>>
"Mensanator" <me********@aol.comwrote in message
news:bb**********************************@a1g2000h sb.googlegroups.com...
| On Jun 5, 10:42?pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
| Is it possible to write a list comprehension for this so as to produce
a
| list of two-item tuples?
| >
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
| >
| I can't think of how the structure of the list comprehension would work
| in this case, because it seems to require iteration over two separate
| sequences to produce each item in the tuple.
Which is exactly the purpose of zip, or its specialization enumerate!
| zip seems to work fine anyway, but my immediate instinct was to try a
| list comprehension (until I couldn't figure out how!). And I wasn't
sure
| if list comps were capable of doing everything a zip could do.
|
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
|
| s = [(i+8,j) for i,j in enumerate( [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3])]
| print s
|
| ##>>>
| ##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
| 2), (16, 2), (17, 3), (18, 3)]
| ##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
| 2), (16, 2), (17, 3), (18, 3)]
| ##>>>
Of course, enumerate(iterable) is just a facade over zip(itertools.count(),
iterable)
On Jun 6, 8:44*am, "Terry Reedy" <tjre...@udel.eduwrote:
>
Of course, enumerate(iterable) is just a facade over zip(itertools.count(),
iterable)
So you could write:
gen = (x for x in itertools.izip(itertools.count(8), [0, 1, 1, 1, 1,
1, 1, 2, 2, 3, 3]))
print list(gen)
Using zip like you own example is the best option.
If you have a huge amount of data and only want to iterate over the
result, using a generator is probably better:
gen = (x for x in itertools.izip(itertools.count(8), [0, 1, 1, 1, 1,
1, 1, 2, 2, 3, 3]))
for i, j in gen:
... your code here ...
On Thu, 05 Jun 2008 23:56:40 -0700, dwahli wrote:
On Jun 6, 8:44Â*am, "Terry Reedy" <tjre...@udel.eduwrote:
>> Of course, enumerate(iterable) is just a facade over zip(itertools.count(), iterable)
So you could write:
gen = (x for x in itertools.izip(itertools.count(8), [0, 1, 1, 1, 1,
1, 1, 2, 2, 3, 3]))
print list(gen)
Useless use of a generator expression. This:
gen = itertools.izip(itertools.count(8), [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3])
print list(gen)
has the same effect without the intermediate generator that does nothing
but passing the items.
Ciao,
Marc 'BlackJack' Rintsch
"Terry Reedy" <tj*****@udel.eduwrote in message
news:ma*************************************@pytho n.org...
>
"Mensanator" <me********@aol.comwrote in message
news:bb**********************************@a1g2000h sb.googlegroups.com...
Which is exactly the purpose of zip, or its specialization enumerate!
Thanks guys! Looks like the simplest is always the best yet again! :)
On Jun 6, 1:44*am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:bb**********************************@a1g2000h sb.googlegroups.com...
| On Jun 5, 10:42?pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
| Is it possible to write a list comprehension for this so as to produce
a
| list of two-item tuples?
| >
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
| >
| I can't think of how the structure of the list comprehension would work
| in this case, because it seems to require iteration over two separate
| sequences to produce each item in the tuple.
Which is exactly the purpose of zip, or its specialization enumerate!
Aren't you overlooking the fact that zip() truncates the output
to the shorter length iterable? And since the OP foolishly
hardcoded his range bounds, zip(base_scores,score_cost) will
silently return the wrong answer if the base_count list grows.
Surely enumerate() wasn't added to Python with no intention of
ever being used.
>
| zip seems to work fine anyway, but my immediate instinct was to try a
| list comprehension (until I couldn't figure out how!). And I wasn't
sure
| if list comps were capable of doing everything a zip could do.
|
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
|
| s = [(i+8,j) for i,j in enumerate( [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3])]
| print s
|
| ##>>>
| ##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
| 2), (16, 2), (17, 3), (18, 3)]
| ##[(8, 0), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15,
| 2), (16, 2), (17, 3), (18, 3)]
| ##>>>
Of course, enumerate(iterable) is just a facade over zip(itertools.count(),
iterable)
But if all I'm using itertools for is the count() function, why would
I
go to the trouble of importing it when I can simply use enumerate()?
Is it a couple orders of magnitude faster?
On Thu, 05 Jun 2008 23:42:07 -0400, John Salerno wrote:
Is it possible to write a list comprehension for this so as to produce a
list of two-item tuples?
base_scores = range(8, 19)
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3] print zip(base_scores,
score_costs)
score_costs = [(base_scores[i], score_costs[i]) for i in range (len
(base_scores))]
But, I'd rather just use zip. :-)
--
code.py: A blog about life, the universe, and Python http://pythonista.wordpress.com
** Posted from http://www.teranews.com **
"Mensanator" <me********@aol.comwrote in message
news:c5**********************************@z72g2000 hsb.googlegroups.com...
On Jun 6, 1:44 am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
And since the OP foolishly
hardcoded his range bounds
Hmm, I just love the arrogance of some people. I actually posted a response
to my own thread that asked about this situation of how best to make the
range, but it doesn't seem to have posted.
On Jun 6, 3:19*pm, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:c5**********************************@z72g2000 hsb.googlegroups.com...
On Jun 6, 1:44 am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
And since the OP foolishly
hardcoded his range bounds
Hmm, I just love the arrogance of some people. I actually posted a response
to my own thread that asked about this situation of how best to make the
range, but it doesn't seem to have posted.
It wasn't meant to be arrogant. Just that you must be careful
with zip() because it will not throw an exception if the two
iterables are of different length (this behaviour is by design)
but simply return tuples for the shorter of the iterables.
Hardcoding the range bounds instead of setting them dynamically
is a classic cause of this type of error. Obviously, you want the
range to start with 8, but what should be the upper bound?
The start plus the length of the other iterable keeping in mind
that if length is 11, last index is 8+10 since counting starts at 0.
So you want
range(8,8+len(score_costs))
Using enumerate() means you don't have to figure this out and
you'll never get an error or bad results that don't make an
error.
On Jun 6, 1:40*pm, The Pythonista <n...@this.timewrote:
On Thu, 05 Jun 2008 23:42:07 -0400, John Salerno wrote:
Is it possible to write a list comprehension for this so as to produce a
list of two-item tuples?
base_scores = range(8, 19)
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3] print zip(base_scores,
score_costs)
score_costs = [(base_scores[i], score_costs[i]) for i in range (len
(base_scores))]
What happens if your iterables aren't the same length?
>
But, I'd rather just use zip. :-)
And with zip() you won't get an error, but it won't be correct,
either.
>
--
code.py: A blog about life, the universe, and Python
http://pythonista.wordpress.com
** Posted fromhttp://www.teranews.com**
"Mensanator" <me********@aol.comwrote in message
news:c5**********************************@z72g2000 hsb.googlegroups.com...
On Jun 6, 1:44 am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:bb**********************************@a1g2000h sb.googlegroups.com...
| On Jun 5, 10:42?pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
| Is it possible to write a list comprehension for this so as to
produce
a
| list of two-item tuples?
| >
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
| >
| I can't think of how the structure of the list comprehension would
work
| in this case, because it seems to require iteration over two separate
| sequences to produce each item in the tuple.
Which is exactly the purpose of zip, or its specialization enumerate!
Aren't you overlooking the fact that zip() truncates the output
to the shorter length iterable?
=========================
<message does not quote correctly>
<meNo.
=========================
And since the OP foolishly
hardcoded his range bounds, zip(base_scores,score_cost) will
silently return the wrong answer if the base_count list grows.
============
<meSo, to future proof his code he should better use
zip(itertools.count(8), score_costs). I consider this better than using
enumerate to make the wrong pairing (with itertools.count(0)) and then
correcting the mistake.
====================
Surely enumerate() wasn't added to Python with no intention of
ever being used.
========================
<meOf course not, so why suggest that is was?
However, it was intended for the most common case when one wants to pair
items with counts beginning with 0.
=================================
Of course, enumerate(iterable) is just a facade over
zip(itertools.count(),
iterable)
But if all I'm using itertools for is the count() function, why would
I go to the trouble of importing it when I can simply use enumerate()?
====================================
<me>I have no idea. The purpose of enumerate is to be easy.
But it is not so easy when it gives the wrong pairings.
===================================
Is it a couple orders of magnitude faster?
=================================
<mePerhaps you do not understand 'facade' - the front part or face of
something that you see. I was saying that enumerate is a face on a room
containing zip and itertools.count, or the equivalent code thereof.
Therefore, enumerate is an easy way to do a particular zip, not an
alternative to zip. And there should be no significant performance
difference, certainly for long sequences which make the additional lookups
irrelevant.
tjr
On Jun 6, 10:33*pm, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:c5**********************************@z72g2000 hsb.googlegroups.com...
On Jun 6, 1:44 am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:bb**********************************@a1g2000h sb.googlegroups.com...
| On Jun 5, 10:42?pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
| Is it possible to write a list comprehension for this so as to
produce
a
| list of two-item tuples?
| >
| base_scores = range(8, 19)
| score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
| print zip(base_scores, score_costs)
| >
| I can't think of how the structure of the list comprehension would
work
| in this case, because it seems to require iteration over two separate
| sequences to produce each item in the tuple.
Which is exactly the purpose of zip, or its specialization enumerate!
Aren't you overlooking the fact that zip() truncates the output
to the shorter length iterable?
=========================
<message does not quote correctly>
<meNo.
=========================
And since the OP foolishly
hardcoded his range bounds, zip(base_scores,score_cost) will
silently return the wrong answer if the base_count list grows.
============
<meSo, to future proof his code he should better use
zip(itertools.count(8), score_costs). *I consider this better than using
enumerate to make the wrong pairing (with itertools.count(0)) and then
correcting the mistake.
Mistake? How is starting at 0 a mistake? Because .count() can
start at 8, eliminating the i+8 construction? But what if
I wanted to count by two or want a sequence cubes that start
at 8? Can itertools do that? I would say knowing how to
manipulate a 0-based iterable will pay off more in the long
run. If you don't know how to get the index numbers you want
from enumerate(), itertools isn't going to help.
====================
Surely enumerate() wasn't added to Python with no intention of
ever being used.
========================
<meOf course not, so why suggest that is was?
However, it was intended for the most common case when one wants to pair
items with counts beginning with 0.
=================================
Of course, enumerate(iterable) is just a facade over
zip(itertools.count(),
iterable)
But if all I'm using itertools for is the count() function, why would
I go to the trouble of importing it when I can simply use enumerate()?
====================================
<me>I have no idea. *The purpose of enumerate is to be easy.
But it is not so easy when it gives the wrong pairings.
The same can be said of zip() if you're not careful
about the size of the iterables. There is no substitute
for understanding how things work.
===================================
Is it a couple orders of magnitude faster?
=================================
<mePerhaps you do not understand 'facade' - the front part or face of
something that you see. *
Well, I also understand the secondary meaning:
2. An artificial or deceptive front
I was saying that enumerate is a face on a room
containing zip and itertools.count, or the equivalent code thereof.
I thought you were trying to imply that to use enumerate()
is to be un-Pythonic, that _real_ programmers always use
itertools.
Therefore, enumerate is an easy way to do a particular zip, not an
alternative to zip. *
Ok, I mistook your use of 'facade' for arrogance,
just as the OP mistook my use of 'foolishly' for
arrogance. Ain't English wonderful?
And there should be no significant performance
difference, certainly for long sequences which make the additional lookups
irrelevant.
tjr
On Fri, 06 Jun 2008 18:01:45 -0700, Mensanator wrote:
What happens if your iterables aren't the same length?
I chose not to consider that case, since they were the same length in the
original post. Based on the variable names, it seemed reasonable that
there would always be a 1-to-1 correspondence between elements of each
list. However, if you do
score_costs = [(base_scores[i], score_costs[i]) for i in range (min (len
(base_scores), len (score_costs))]
then you get exactly what you would get using zip. That's one heck of a
long line, though, hence my earlier comment:
>But, I'd rather just use zip. :-)
And with zip() you won't get an error, but it won't be correct, either.
If it doing what zip() does makes sense, then just use zip(). Otherwise,
check for the case where the iterables are of different length, and do
the appropriate thing (raise an error, pad the shorter one, whatever).
--
code.py: a blog about Python. http://pythonista.wordpress.com
** Posted from http://www.teranews.com **
On Jun 7, 5:21�am, Paul Miller <n...@this.timewrote:
On Fri, 06 Jun 2008 18:01:45 -0700, Mensanator wrote:
What happens if your iterables aren't the same length?
I chose not to consider that case,
That's a bad habit to teach a newbie, isn't it?
since they were the same length in the
original post. �
The issue I'm stressing is HOW they got to be
the same size. If I was teaching programming
and the OP turned in that example, I would mark
him down. Not because he got the answer wrong.
Not because he used zip. Not because he failed
to use enumerate or itertools. But because he
hardcoded the array bounds and THAT'S the lesson
the OP should take away from this.
Based on the variable names, it seemed reasonable that
there would always be a 1-to-1 correspondence between
elements of each list. �
Yes, reasonable at the time. But this is Python,
not C. Lists can change size under program control,
a feature that's extremely useful. But there's a
price for that usefulness. Practices that made
sense in C (define a constant to set array bounds)
aren't transportable over to systems that simply
don't have the restrictions that require those
practices.
However, if you do
score_costs = [(base_scores[i], score_costs[i]) for i in range (min (len
(base_scores), len (score_costs))]
then you get exactly what you would get using zip. �
And if the iterables change size dynamically, you
could get either a crash due to index out of range
or else silently a wrong answer.
That's one heck of a
long line, though, hence my earlier comment:
I have no problem telling the OP this method.
But I think you should warn him about potential
problems.
Surely you didn't intend to leave him to twist
in the wind so that he learns a thing or two
when his programs crash?
>
But, I'd rather just use zip. :-)
And with zip() you won't get an error, but it won't be correct, either.
If it doing what zip() does makes sense, then just use zip(). �Otherwise,
check for the case where the iterables are of different length, and do
the appropriate thing (raise an error, pad the shorter one, whatever).
That's all I'm suggesting. Along with pointing out
that enumerate or itertools can do this for him.
>
--
code.py: a blog about Python. �http://pythonista.wordpress.com
** Posted fromhttp://www.teranews.com**
Mensanator wrote:
Surely enumerate() wasn't added to Python with no intention of
ever being used.
I see your reasons for preferring enumerate over zip, but I'm wondering
if using enumerate this way isn't a little hackish or artificial. Isn't
the point of enumerate to get the index of a specific item, as well as
that item itself? It seems like arbitrarily altering the index (i+8) is
an abuse of enumerate's true purpose.
Does this make any sense, or is it generally acceptable to use enumerate
like this?
On Jun 7, 1:16�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
Surely enumerate() wasn't added to Python with no intention of
ever being used.
I see your reasons for preferring enumerate over zip,
It's not that I prefer it, it's that you specifically
asked a list comprehension and I gave you one. I use
zip when I need to, but I would never use it with a
range function unless I'm deliberately creating a
subset (where you certainly don't want to use enumerate).
but I'm wondering if using enumerate this way isn't
a little hackish or artificial.
I wouldn't say so. An index can be part of the
data structure - a part that doesn't have to be
stored, it's implied. And just like everything
else, this entails a certain responsibility on
your part that the data you are storing is indexed
correctly.
Isn't the point of enumerate to get the index
of a specific item, as well as that item itself?
I would say that's the main point but not the
only point. It's handy when you have multiple
iterables that are related by their position.
But even in a single iterable the position can
be part of the data structure.
It seems like arbitrarily altering the index (i+8) is
an abuse of enumerate's true purpose.
It's not an abuse because we aren't using (i+8) as
an index, it's simply data. Your point would be
more valid if we turned around and used (i+8) as
an index into another iterable. Not that we couldn't
do it, but we would have to be concerned about
"out of range" errors.
>
Does this make any sense,
It makes as much sense as range(8,19).
or is it generally acceptable to use enumerate
like this?
I use enumerate frequently, and often the index
isn't used as an index. Let me ive you an example:
Say I have a list sv=[1,2,3,4].
What does this list represent? It represents
the contiguous n/2 operations in a sequence from
the Collatz Conjecture. If you know that, you should
immediately ask why I'm not counting the 3n+1
operations? Ah, but I AM counting them. In the CC,
every block of contiguous n/2 operations is seperated
by EXACTLY one 3n+1 operation. So the list structure
implies that every number is preceeded by a single
3n+1 operation. Thus, I don't have to waste memory
counting the 3n+1 blocks because the count is ALWAYS
one and ALWAYS precedes each number in the list.
Now, there's a real nice function you can derive from
any given list. The function is always the same but
it contains three constants (X,Y,Z) that have to be
derived from the list. X is simply 2**sum(sv). Y is
simply 3**len(sv).
But Z is much trickier. For every term in sv, there
is a term that's a power of 3 times a power of 2,
all of which must be summed to get Z.
>>sv =[1,2,3,4] b = [2**i for i in sv] b
[2, 4, 8, 16]
Here I'm simply using the elements of sv to compute
the powers of 2. Nothing special here.
>>c = [3**i for i,j in enumerate(sv)] c
[1, 3, 9, 27]
Here, I'm using the index to find the powers of 3.
Note that j isn't being used. But, I can then
combine them thusly:
>>d = [3**i*2**j for i,j in enumerate(sv)] d
[2, 12, 72, 432]
Here the index isn't being used as an index at all,
it's an integral part of the data structure that
can be extracted along with the physical contents
of the list by using enumerate.
Actually, that formula doesn't give the right
answer, it was just a demo. The true formula
would be this:
>>f = [3**i*2**(sum(sv[:len(sv)-i-1])) for i,j in enumerate(sv)] f
[64, 24, 18, 27]
>>Z = sum(f) Z
133
Although in my actual collatz_functions library I use
for i in xrange(svll,-1,-1):
z = z + (TWE**i * TWO**sum(itertools.islice(sv,0,svll-i)))
Which I csn use to check the above answer.
>>import collatz_functions as cf xyz = cf.calc_xyz(sv) xyz[2]
mpz(133)
Maybe I've gone beyond enumerate's true purpose,
but I find it hard to imagine the designers not
anticipating such useage.
"John Salerno" <jo******@gmailNOSPAM.comwrote in message
news:48***********************@cv.net...
| Mensanator wrote:
|
| Surely enumerate() wasn't added to Python with no intention of
| ever being used.
|
| I see your reasons for preferring enumerate over zip, but I'm wondering
| if using enumerate this way isn't a little hackish or artificial.
It seems to be a difference of personal preference. I see no reason to
write a for loop (statement or expression) when a simple usage of basic
builtins does the same. Mensanator apparently does. So it goes.
Because zip stops when the first iterator is exhausted, the original zip
with range can be pretty well future proofed with a high stop value.
zip(range(9,2000000000), iterable)
Of course, a non-1 step can be added to the range.
tjr
On Jun 7, 6:43�pm, "Terry Reedy" <tjre...@udel.eduwrote:
"John Salerno" <johnj...@gmailNOSPAM.comwrote in message
news:48***********************@cv.net...| Mensanator wrote:
|
| Surely enumerate() wasn't added to Python with no intention of
| ever being used.
|
| I see your reasons for preferring enumerate over zip, but I'm wondering
| if using enumerate this way isn't a little hackish or artificial.
It seems to be a difference of personal preference. �I see no reason to
write a for loop (statement or expression) when a simple usage of basic
builtins does the same. �Mensanator apparently does. �
*sigh* I never said a for..loop was preferable.
What I said was the answer to "Can I do this with
a list comprehension?"
I never said you shouldn't use the builtins.
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
So it goes.
So I was trying to help the guy out. So sue me.
>
Because zip stops when the first iterator is exhausted, the original zip
with range can be pretty well future proofed with a high stop value.
zip(range(9,2000000000), iterable)
Oh, dear. You didn't actually try this, did you?
>
Of course, a non-1 step can be added to the range.
I would hope so, otherwise you're going to have
a problem creating a list with two billion integers.
You might want to try xrange() in your production code.
>
tjr
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of the two
arguments, and also in my case the two arguments would always be the
same length. But it is still helpful for other people to point out to me
potential problems like this, so I can be aware of it the next time I
might want to use zip with unequal length arguments.
On Jun 7, 7:21*pm, Paul Miller <n...@this.timewrote:
On Fri, 06 Jun 2008 18:01:45 -0700, Mensanator wrote:
What happens if your iterables aren't the same length?
I chose not to consider that case, since they were the same length in the
original post. *Based on the variable names, it seemed reasonable that
there would always be a 1-to-1 correspondence between elements of each
list.
If you think something is true but want to guarantee it, use assert.
Then when your assumption is wrong at least you find out.
assert len(base_scores) == len(score_costs)
score_costs = zip(base_scores, score_costs)
--
Paul Hankin
On Jun 7, 8:22�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of the two
arguments,
Ok, sorry I thought otherwise.
and also in my case the two arguments would always be the
same length.
Yes, because you're controlling the source code.
But since lists are mutable, source code literals
don't always control the length of the list.
But it is still helpful for other people to point out to me
potential problems like this,
My intentions were always to be helpful, not arrogant.
Otherwise, I'd just tell you to go RTFM. I do seem to have
a gift for rubbing people the wrong way.
What's important at the end of the day is that you
have a working program, right?
so I can be aware of it the next time I
might want to use zip with unequal length arguments.
There are, of course, situations where that's
desireable, that's why I said such behaviour is
by design. It's much easier to debug a program
that crahes than one that works but gives you
the wrong answer. You'll find the "out of range"
errors readily enough, it's when the list is longer
than the range and the answer comes up short that
are hard to spot.
That previous example I gave you? I've run that
with a list of over 800,000 numbers, far too many
to manually verify. I must have absolute confidence
that the algorithm works correctly. That's what
you should strive for - confidence that things will
work even when you can't manually verify them.
"Mensanator" <me********@aol.comwrote in message
news:8d**********************************@2g2000hs n.googlegroups.com...
| On Jun 7, 6:43?pm, "Terry Reedy" <tjre...@udel.eduwrote:
| zip(range(9,2000000000), iterable)
|
| Oh, dear. You didn't actually try this, did you?
Works fine in Py3, which is what I use now.
On Jun 8, 12:24Â*am, Mensanator <mensana...@aol.comwrote:
On Jun 7, 5:21�am, Paul Miller <n...@this.timewrote:
On Fri, 06 Jun 2008 18:01:45 -0700, Mensanator wrote:
What happens if your iterables aren't the same length?
I chose not to consider that case,
That's a bad habit to teach a newbie, isn't it?
since they were the same length in the
original post. �
The issue I'm stressing is HOW they got to be
the same size. If I was teaching programming
and the OP turned in that example, I would mark
him down. Not because he got the answer wrong.
Not because he used zip. Not because he failed
to use enumerate or itertools. But because he
hardcoded the array bounds and THAT'S the lesson
the OP should take away from this.
Mark him down? Rather blind attack on the approach. If I have a
variable coord that contains (x, y, z) and I hardcoded their meanings
and bounds, you're still marking me down for the possibility of adding
a fourth dimension? While I'm aware that I won't ever be concerned by
the fourth, fifth, ... dimensions ever in my life.
In some usage, hardcoding has no harm and in fact might be useful.
If I have a data that contains 8 sections, and I know that since this
is a low level protocol, it's not going to grow legs and arms. It's
natural to use a list/tuple and hardcode the datas length.
Based on the variable names, it seemed reasonable that
there would always be a 1-to-1 correspondence between
elements of each list. �
Yes, reasonable at the time. But this is Python,
not C. Lists can change size under program control,
a feature that's extremely useful. But there's a
price for that usefulness. Practices that made
sense in C (define a constant to set array bounds)
aren't transportable over to systems that simply
don't have the restrictions that require those
practices.
However, if you do
score_costs = [(base_scores[i], score_costs[i]) for i in range (min (len
(base_scores), len (score_costs))]
then you get exactly what you would get using zip. �
And if the iterables change size dynamically, you
could get either a crash due to index out of range
or else silently a wrong answer.
That's one heck of a
long line, though, hence my earlier comment:
I have no problem telling the OP this method.
But I think you should warn him about potential
problems.
Surely you didn't intend to leave him to twist
in the wind so that he learns a thing or two
when his programs crash?
That's the best way to learn: "making mistakes".
You don't learn anything if you never make mistakes.
If it doing what zip() does makes sense, then just use zip(). �Otherwise,
check for the case where the iterables are of different length, and do
the appropriate thing (raise an error, pad the shorter one, whatever).
That's all I'm suggesting. Along with pointing out
that enumerate or itertools can do this for him.
I think it's up to the OP, not you, to decide whether the use of bare
zip is enough and whether data truncation might or might not be a
problem. It seems that since he has used zip in his original post, he
thought it fits his situation best, perhaps its truncation behavior is
something he wanted to exploit in the first place.
On Jun 8, 8:56Â*am, Mensanator <mensana...@aol.comwrote:
On Jun 7, 8:22�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of the two
arguments,
Ok, sorry I thought otherwise.
and also in my case the two arguments would always be the
same length.
Yes, because you're controlling the source code.
But since lists are mutable, source code literals
don't always control the length of the list.
Since when source code literals ever control the length of a list?
What controls the length of the list is the semantic meaning of the
list, in some cases it just makes no sense that the list would ever
have different length.
(snip)
On Jun 8, 3:19�am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
news:8d**********************************@2g2000hs n.googlegroups.com...
| On Jun 7, 6:43?pm, "Terry Reedy" <tjre...@udel.eduwrote:
| zip(range(9,2000000000), iterable)
|
| Oh, dear. You didn't actually try this, did you?
Works fine in Py3, which is what I use now.
You really ARE cruel to the newbies, aren't you?
Don't you think it would have been appropriate
to attach a large red label: WARNING! PY3!
On Jun 8, 4:04Â*am, Lie <Lie.1...@gmail.comwrote:
On Jun 8, 8:56Â*am, Mensanator <mensana...@aol.comwrote:
On Jun 7, 8:22�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of the two
arguments,
Ok, sorry I thought otherwise.
and also in my case the two arguments would always be the
same length.
Yes, because you're controlling the source code.
But since lists are mutable, source code literals
don't always control the length of the list.
Since when source code literals ever control the length of a list?
Isn't score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
considered a literal?
What controls the length of the list is the semantic meaning of the
list,
Wha do you mean by that? The list contains 11 objects.
How could the length be any different?
in some cases it just makes no sense that the list would ever
have different length.
And in such case there won't be any problem, will there?
Is that a good habit to teach a newbie? To write
code that only works for special cases?
>
(snip)- Hide quoted text -
- Show quoted text -
Mensanator wrote:
On Jun 8, 3:19�am, "Terry Reedy" <tjre...@udel.eduwrote:
>"Mensanator" <mensana...@aol.comwrote in message
news:8d**********************************@2g2000h sn.googlegroups.com... | On Jun 7, 6:43?pm, "Terry Reedy" <tjre...@udel.eduwrote: | zip(range(9,2000000000), iterable) | | Oh, dear. You didn't actually try this, did you?
Works fine in Py3, which is what I use now.
You really ARE cruel to the newbies, aren't you?
Don't you think it would have been appropriate
to attach a large red label: WARNING! PY3!
Heh heh, don't worry. Every time I see a range function, I immediately
think "creates a list". Not sure how I got into that habit, but it
happens every time! :)
On Jun 8, 9:40Â*pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
On Jun 8, 3:19�am, "Terry Reedy" <tjre...@udel.eduwrote:
"Mensanator" <mensana...@aol.comwrote in message
>news:8d**********************************@2g2000h sn.googlegroups.com...
| On Jun 7, 6:43?pm, "Terry Reedy" <tjre...@udel.eduwrote:
| zip(range(9,2000000000), iterable)
|
| Oh, dear. You didn't actually try this, did you?
Works fine in Py3, which is what I use now.
You really ARE cruel to the newbies, aren't you?
Don't you think it would have been appropriate
to attach a large red label: WARNING! PY3!
Heh heh, don't worry. Every time I see a range function, I immediately
think "creates a list". Not sure how I got into that habit, but it
happens every time! :)
You probably got into that habit because that's
what it does in 2.x, create a list. Now, if
you're expecting that to happen you'll in for
a surprise when you switch to Py3, won't you?
Mensanator wrote:
On Jun 6, 1:40 pm, The Pythonista <n...@this.timewrote:
>On Thu, 05 Jun 2008 23:42:07 -0400, John Salerno wrote:
>>Is it possible to write a list comprehension for this so as to produce a list of two-item tuples? base_scores = range(8, 19) score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3] print zip(base_scores, score_costs)
score_costs = [(base_scores[i], score_costs[i]) for i in range (len (base_scores))]
What happens if your iterables aren't the same length?
>But, I'd rather just use zip. :-)
And with zip() you won't get an error, but it won't be correct,
either.
Wouldn't it be nice to have leftZip(), rightZip(), and fullZip() for
when the lists have different lengths? The final tuples for a leftZip
could be in the form (value, ) and for right zip (, value) (though I
think this last tuple is not allowed in python's syntax, we might define
a "Null" or "Empty" name to act as a place holder in the resulting tuples).
On Jun 9, 7:06*am, Ricardo Aráoz <ricar...@gmail.comwrote:
Mensanator wrote:
On Jun 6, 1:40 pm, The Pythonista <n...@this.timewrote:
On Thu, 05 Jun 2008 23:42:07 -0400, John Salerno wrote: Is it possible to write a list comprehension for this so as to producea list of two-item tuples? base_scores = range(8, 19) score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3] print zip(base_scores, score_costs)
score_costs = [(base_scores[i], score_costs[i]) for i in range (len
(base_scores))]
What happens if your iterables aren't the same length?
But, I'd rather just use zip. :-)
And with zip() you won't get an error, but it won't be correct,
either.
Wouldn't it be nice to have leftZip(), rightZip(), and fullZip() for
when the lists have different lengths? The final tuples for a leftZip
could be in the form (value, ) and for right zip (, value) (though I
think this last tuple is not allowed in python's syntax, we might define
a "Null" or "Empty" name to act as a place holder in the resulting tuples)..
You can go
zip(xrange(9, 10000000000L), [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3])
since xrange DOES NOT return a list but a constant-memory iterable.
Also, there is itertools for adding default values after you fall off
the end of a list.
>>import itertools zip(xrange(100), itertools.chain([0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3], itertools.cycle([None])))
Whose output is:
[(0, 0), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 2), (8,
2), (9, 3), (10, 3), (11, None), (12, None), (13, None), (14, None),
(15, None), (16, None), (17, None), (18, None), (19, None), (20,
None), (21, None), (22, None), (23, None), (24, None), (25, None),
(26, None), (27, None), (28, None), (29, None), (30, None), (31,
None), (32, None), (33, None), (34, None), (35, None), (36, None),
(37, None), (38, None), (39, None), (40, None), (41, None), (42,
None), (43, None), (44, None), (45, None), (46, None), (47, None),
(48, None), (49, None), (50, None), (51, None), (52, None), (53,
None), (54, None), (55, None), (56, None), (57, None), (58, None),
(59, None), (60, None), (61, None), (62, None), (63, None), (64,
None), (65, None), (66, None), (67, None), (68, None), (69, None),
(70, None), (71, None), (72, None), (73, None), (74, None), (75,
None), (76, None), (77, None), (78, None), (79, None), (80, None),
(81, None), (82, None), (83, None), (84, None), (85, None), (86,
None), (87, None), (88, None), (89, None), (90, None), (91, None),
(92, None), (93, None), (94, None), (95, None), (96, None), (97,
None), (98, None), (99, None)]
"Mensanator" <me********@aol.comwrote in message
news:f5**********************************@34g2000h sh.googlegroups.com...
On Jun 8, 9:40 pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
Heh heh, don't worry. Every time I see a range function, I immediately
think "creates a list". Not sure how I got into that habit, but it
happens every time! :)
You probably got into that habit because that's
what it does in 2.x, create a list. Now, if
you're expecting that to happen you'll in for
a surprise when you switch to Py3, won't you?
Nah, I know about the change.It might be a slight adjustment at first, but
probably a good one.
On Jun 8, 11:11Â*pm, Mensanator <mensana...@aol.comwrote:
On Jun 8, 4:04Â*am, Lie <Lie.1...@gmail.comwrote:
On Jun 8, 8:56Â*am, Mensanator <mensana...@aol.comwrote:
On Jun 7, 8:22�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of the two
arguments,
Ok, sorry I thought otherwise.
and also in my case the two arguments would always be the
same length.
Yes, because you're controlling the source code.
But since lists are mutable, source code literals
don't always control the length of the list.
Since when source code literals ever control the length of a list?
Isn't score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
considered a literal?
Yep, but it's not the sole controller of the length of a list. There
are other things that might control the length of the list like del,
append, etc.
What controls the length of the list is the semantic meaning of the
list,
Wha do you mean by that? The list contains 11 objects.
How could the length be any different?
What I meant is in some cases (not all) the list might semantically be
nonsense if it is of different length (i.e. it have fixed length).
in some cases it just makes no sense that the list would ever
have different length.
And in such case there won't be any problem, will there?
Is that a good habit to teach a newbie? To write
code that only works for special cases?
I think it is up to the programmer to decide whether special case is
enough or a general case is necessary.
On Jun 10, 6:09Â*pm, Lie <Lie.1...@gmail.comwrote:
On Jun 8, 11:11Â*pm, Mensanator <mensana...@aol.comwrote:
On Jun 8, 4:04Â*am, Lie <Lie.1...@gmail.comwrote:
On Jun 8, 8:56Â*am, Mensanator <mensana...@aol.comwrote:
On Jun 7, 8:22�pm, John Salerno <johnj...@gmailNOSPAM.comwrote:
Mensanator wrote:
What I DID say was that how the builtins actually
work should be understood and it APPEARED that the
OP didn't understand that. Maybe he understood that
all along but his example betrayed no evidence of
that understanding.
Well, the truth is that I know zip truncates to the shorter of thetwo
arguments,
Ok, sorry I thought otherwise.
and also in my case the two arguments would always be the
same length.
Yes, because you're controlling the source code.
But since lists are mutable, source code literals
don't always control the length of the list.
Since when source code literals ever control the length of a list?
Isn't score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
considered a literal?
Yep, but it's not the sole controller of the length of a list. There
are other things that might control the length of the list like del,
append, etc.
I believe I just said that. Perhaps I should have said
at the instant it's created, the length is determined
by the literal.
Remember,
score_costs = [0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3]
is preceeded by range(11), so of course AT THAT INSTANT,
the lengths match. But, as you say, there's no guarantee
that the list lengths will remain unchanged.
And that's why I'm saying it isn't necessarily a good idea
to assume that. For the way it's used, the zip function
IS assuming that.
>
What controls the length of the list is the semantic meaning of the
list,
Wha do you mean by that? The list contains 11 objects.
How could the length be any different?
What I meant is in some cases (not all) the list might semantically be
nonsense if it is of different length (i.e. it have fixed length).
Sure, but remember, the OP was asking how to do this in a
list comprehension where he doesn't have the option of
iterating through both lists like he does with zip.
When I mentioned that could be solved by enumerate, I said
it simultaneously guaratees that the index numbers automatically
end up the same length as the target list and avoids the
hypothetical case where the list lengths somehow don't match.
Of course nothing can be done if the actual list length is
semantically nonsense and you actually might need to exploit
the truncating of the list to a fixed range. But there are
many cases where you DON'T want that to happen (if you deposit
5 checks at the bank, you certainly want credit for ALL of them,
not just some idiot's notion that only 4 can be deposited in
a single transaction.)
>
in some cases it just makes no sense that the list would ever
have different length.
And in such case there won't be any problem, will there?
Is that a good habit to teach a newbie? To write
code that only works for special cases?
I think it is up to the programmer to decide whether special case is
enough or a general case is necessary.
Yes, he can certainly decide. Provided he knows what all the
options are. There's no way to tell if the OP understands
what the options are. I say it's always better to supply too
much information than not enough. Assume the reader is clever
enough to seperate the wheat from the chaff. If it turns out
he's not, then I at least _I_ will be blameless. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Fuzzyman |
last post by:
Pythons internal 'pointers' system is certainly causing me a few
headaches..... When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or*...
|
by: Moosebumps |
last post by:
Does anyone here find the list comprehension syntax awkward?
I like it because it is an expression rather than a series of statements,
but it is a little harder to maintain it seems.
e.g. you...
|
by: Chris P. |
last post by:
Hi. I've made a program that logs onto a telnet server, enters a
command, and then creates a list of useful information out of the
information that is dumped to the screen as a result of the...
|
by: jena |
last post by:
hello,
when i create list of lambdas:
l=]
then l() returns 'C', i think, it should be 'A'
my workaround is to define helper class with __call__ method:
class X:
def __init__(self,s): self.s=s...
|
by: a |
last post by:
can someone tell me how to use them
thanks
|
by: Gregory Guthrie |
last post by:
Sorry for a simple question- but I don't understand how to parse this use of
a list comprehension.
The "or" clauses are odd to me.
It also seems like it is being overly clever (?) in using a...
|
by: bullockbefriending bard |
last post by:
Given:
class Z(object):
various defs, etc.
class ZList(list):
various defs, etc.
i would like to be able to replace
|
by: beginner |
last post by:
Hi,
Does anyone know how to put an assertion in list comprehension? I have
the following list comprehension, but I want to use an assertion to
check the contents of rec_stdl. I ended up using...
|
by: Debajit Adhikary |
last post by:
I have two lists:
a =
b =
What I'd like to do is append all of the elements of b at the end of
a, so that a looks like:
a =
|
by: beginner |
last post by:
Hi All,
If I have a list comprehension:
ab=
c = "ABC"
print c
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM).
In this month's session, the creator of the excellent VBE...
|
by: MeoLessi9 |
last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
|
by: DolphinDB |
last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation.
Take...
|
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...
|
by: Aftab Ahmad |
last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below.
Dim IE As Object
Set IE =...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
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...
|
by: marcoviolo |
last post by:
Dear all,
I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
|
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...
| |