Reading 3 objects at a time from list

M

Matteo

Hi all,
let's see if there is a more "pythonic" way of doing what I'm trying
to do.
I have a lot of strings with numbers like this one:

string = "-1 1.3 100.136 1 2.6 100.726 1 3.9 101.464 -1 5.2 102.105"

I need to pass the numbers to a function, but three at a time, until
the string ends. The strings are of variable length, but always a
multiple of three.

That's what I did:
num = string.split()
for triple in zip(num[::3], num[1::3], num[2::3]):
func(*triple)

it works and I like slices, but I was wondering if there was another
way of doing the same thing, maybe reading the numbers in groups of
arbitrary length n...

any ideas?
 
C

Chris Rebert

Hi all,
let's see if there is a more "pythonic" way of doing what I'm trying
to do.
I have a lot of strings with numbers like this one:

string = "-1 1.3 100.136 1 2.6 100.726 1 3.9 101.464 -1 5.2 102.105"

I need to pass the numbers to a function, but three at a time, until
the string ends. The strings are of variable length, but always a
multiple of three.

That's what I did:
num = string.split()
for triple in zip(num[::3], num[1::3], num[2::3]):
   func(*triple)

it works and I like slices, but I was wondering if there was another
way of doing the same thing, maybe reading the numbers in groups of
arbitrary length n...

See the grouper() recipe in the `itertools` module --
http://docs.python.org/library/itertools.html

Cheers,
Chris
 
F

Francesco Bochicchio

Chris Rebert ha scritto:
Hi all,
let's see if there is a more "pythonic" way of doing what I'm trying
to do.
I have a lot of strings with numbers like this one:

string = "-1 1.3 100.136 1 2.6 100.726 1 3.9 101.464 -1 5.2 102.105"

I need to pass the numbers to a function, but three at a time, until
the string ends. The strings are of variable length, but always a
multiple of three.

That's what I did:
num = string.split()
for triple in zip(num[::3], num[1::3], num[2::3]):
func(*triple)

it works and I like slices, but I was wondering if there was another
way of doing the same thing, maybe reading the numbers in groups of
arbitrary length n...

See the grouper() recipe in the `itertools` module --
http://docs.python.org/library/itertools.html

Cheers,
Chris


I would do that with a generator:
.... while l: yield l[:n]; l=l[n:]
....
>>> list(groups(range(14),4)) [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13]]
>>> list(groups(range(18),3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17]]

Ciao
 
P

Peter Otten

Matteo said:
Hi all,
let's see if there is a more "pythonic" way of doing what I'm trying
to do.
I have a lot of strings with numbers like this one:

string = "-1 1.3 100.136 1 2.6 100.726 1 3.9 101.464 -1 5.2 102.105"

I need to pass the numbers to a function, but three at a time, until
the string ends. The strings are of variable length, but always a
multiple of three.

That's what I did:
num = string.split()
for triple in zip(num[::3], num[1::3], num[2::3]):
func(*triple)

it works and I like slices, but I was wondering if there was another
way of doing the same thing, maybe reading the numbers in groups of
arbitrary length n...

any ideas?

Ideas? Many. But do they make sense?
.... print chunk
....
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9,)
.... print chunk
....
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9,).... items = iter(items)
.... def read(n):
.... return tuple(islice(items, n))
.... return read
........ print chunk
....
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9,)
read = make_read(items)
for n in [3,4,2,1]:
.... print read(n)
....
(0, 1, 2)
(3, 4, 5, 6)
(7, 8)
(9,)
items = iter([3, "a", "b", "c", 2, "p", "q", 4, "x", "y", "z", "t"])
read = make_read(items)
for n in items:
.... print "".join(read(n))
....
abc
pq
xyzt
 
A

Aahz

I would do that with a generator:
... while l: yield l[:n]; l=l[n:]
...

Unfortunately, that's O(N**2) albeit with an extremely small constant
factor, because popping off the head of the list requires a full list
copy. You're probably okay with this algorithm unless the string could
be megabytes.
 
V

Vito De Tullio

Matteo said:
it works and I like slices, but I was wondering if there was another
way of doing the same thing, maybe reading the numbers in groups of
arbitrary length n...

from http://docs.python.org/library/itertools.html#recipes

def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)


and it's *damned* fast!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,293
Messages
2,571,501
Members
48,189
Latest member
StaciLgf76

Latest Threads

Top