Velocity Reviews > Re: for loop question

# Re: for loop question

Tim Chase
Guest
Posts: n/a

 10-10-2007
> test = u"Hello World"
>
> for cur,next in test:
> print cur,next
>
> Ideally, this would output:
>
> 'H', 'e'
> 'e', 'l'
> 'l', 'l'
> 'l', 'o'
> etc...
>
> Of course, the for loop above isn't valid at all. I am just giving an
> example of what I'm trying to accomplish. Anyone know how I can achieve the
> goal in the example above? Thanks.

A "works-for-me":

>>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
>>> for a,b in pairs:

.... print a,b
....
H e
e l
l l
l o
o
w
w o
o r
r l
l d
>>>

-tkc

Paul Hankin
Guest
Posts: n/a

 10-10-2007
On Oct 10, 9:12 pm, Tim Chase <(E-Mail Removed)> wrote:
> > test = u"Hello World"

>
> > for cur,next in test:
> > print cur,next

>
> > Ideally, this would output:

>
> > 'H', 'e'
> > 'e', 'l'
> > 'l', 'l'
> > 'l', 'o'
> > etc...

>
> > Of course, the for loop above isn't valid at all. I am just giving an
> > example of what I'm trying to accomplish. Anyone know how I can achieve the
> > goal in the example above? Thanks.

>
> A "works-for-me":
>
> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
> >>> for a,b in pairs:

> ... print a,b

for a, b in zip(test, test[1:]):
print a, b

--
Paul Hankin

Tim Chase
Guest
Posts: n/a

 10-10-2007
Paul Hankin wrote:
> On Oct 10, 9:12 pm, Tim Chase <(E-Mail Removed)> wrote:
>> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
>> >>> for a,b in pairs:

>> ... print a,b

>
> for a, b in zip(test, test[1:]):
> print a, b

Very nice!

I second this solution as better than my original. The only
"improvement" (in quotes, because it might be more work/opacity
than the problem merits) might be to use izip/islice from
itertools to do the evaluation lazily if "test" gets large:

from itertools import izip, islice
for a,b in izip(test, islice(test, 1, None)):
print a,b

[side note/question]
What's with islice having the first optional paramenter expand as
the stop/third argument by default:

islice(test, 1) -> stop at 1
islice(test, 1, 2) -> start at 1, stop at 2

islice (in python2.4) doesn't even take kword params, so you
can't force it like

islice(test, start=1)

but instead must specify a stop parameter, even if it's None:

islice(test, 1, None)

Seems bogus, IMHO.

-tkc

George Sakkis
Guest
Posts: n/a

 10-10-2007
On Oct 10, 4:12 pm, Tim Chase <(E-Mail Removed)> wrote:

> > test = u"Hello World"

>
> > for cur,next in test:
> > print cur,next

>
> > Ideally, this would output:

>
> > 'H', 'e'
> > 'e', 'l'
> > 'l', 'l'
> > 'l', 'o'
> > etc...

>
> > Of course, the for loop above isn't valid at all. I am just giving an
> > example of what I'm trying to accomplish. Anyone know how I can achieve the
> > goal in the example above? Thanks.

>
> A "works-for-me":
>
> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
> >>> for a,b in pairs:

> ... print a,b
> ...
> H e
> e l
> l l
> l o
> o
> w
> w o
> o r
> r l
> l d
> >>>

>
> -tkc

Or generalized for arbitrary iterables, number of items at a time,
combination function and stopping criterion:

from itertools import islice, takewhile, repeat

def taking(iterable, n, combine=tuple, pred=bool):
iterable = iter(iterable)
return takewhile(pred, (combine(islice(iterable,n)) for _ in
repeat(0)))

>>> for p in taking(test,2): print p

(u'H', u'e')
(u'l', u'l')
(u'o', u' ')
(u'W', u'o')
(u'r', u'l')
(u'd',)

>>> for p in taking(test,2, combine=''.join): print p

He
ll
o
Wo
rl
d

George

Larry Bates
Guest
Posts: n/a

 10-10-2007
Tim Chase wrote:
>> test = u"Hello World"
>>
>> for cur,next in test:
>> print cur,next
>>
>> Ideally, this would output:
>>
>> 'H', 'e'
>> 'e', 'l'
>> 'l', 'l'
>> 'l', 'o'
>> etc...
>>
>> Of course, the for loop above isn't valid at all. I am just giving an
>> example of what I'm trying to accomplish. Anyone know how I can
>> achieve the
>> goal in the example above? Thanks.

>
> A "works-for-me":
>
> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
> >>> for a,b in pairs:

> ... print a,b
> ...
> H e
> e l
> l l
> l o
> o
> w
> w o
> o r
> r l
> l d
> >>>

>
> -tkc
>
>
>

import itertools

test = u"Hello World"
ltest=["'%s'" % c for c in test]

for a, b in itertools.izip(ltest, ltest[1:]):
print x, y

'H' 'e'
'e' 'l'
'l' 'l'
'l' 'o'
'o' ' '
' ' 'W'
'W' 'o'
'o' 'r'
'r' 'l'
'l' 'd'

-Larry

Steven D'Aprano
Guest
Posts: n/a

 10-11-2007
On Wed, 10 Oct 2007 20:25:00 +0000, Paul Hankin wrote:

>> A "works-for-me":
>>
>> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
>> >>> for a,b in pairs:

>> ... print a,b

>
> for a, b in zip(test, test[1:]):
> print a, b

May be unfortunately slow if test is half a gigabyte of data, what with
essentially making three copies of it. Lazy procedures like the generator
expression above are often much better.

Just for completion, here's another way:

prev = test[0]
for i in xrange(1, len(test)):
print prev, test[i]
prev = test[i]

--
Steven.

Paul Hankin
Guest
Posts: n/a

 10-11-2007
On Oct 11, 4:40 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Wed, 10 Oct 2007 20:25:00 +0000, Paul Hankin wrote:
> >> A "works-for-me":

>
> >> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
> >> >>> for a,b in pairs:
> >> ... print a,b

>
> > for a, b in zip(test, test[1:]):
> > print a, b

>
> May be unfortunately slow if test is half a gigabyte of data, what with
> essentially making three copies of it. Lazy procedures like the generator
> expression above are often much better.
>
> Just for completion, here's another way:
>
> prev = test[0]
> for i in xrange(1, len(test)):
> print prev, test[i]
> prev = test[i]

Why not just:

for i in xrange(len(test) - 1):
print test[i], test[i + 1]

--
Paul Hankin

Paul Rubin
Guest
Posts: n/a

 10-11-2007
Steven D'Aprano <(E-Mail Removed)> writes:
> >> >>> pairs = (test[i:i+2] for i in xrange(len(test)-1))
> >> >>> for a,b in pairs:
> >> ... print a,b

> >
> > for a, b in zip(test, test[1:]):
> > print a, b

>
> May be unfortunately slow if test is half a gigabyte of data, what with
> essentially making three copies of it. Lazy procedures like the generator
> expression above are often much better.

Untested:

from itertools import izip, islice
for a,b in izip(test, islice(test,1,None)):
print a,b

seems more natural.