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

generate tuples from sequence

Hi,

I'd like a generator that takes a sequence and yields tuples containing
n items of the sqeuence, but ignoring the 'odd' items. For example

take_group(range(9), 3) -(0,1,2) (3,4,5) (6,7,8)

This is what I came up with..

def take_group(gen, count):
i=iter(gen)
while True:
yield tuple([i.next() for _ in xrange(count)])

Is this the most efficient solution?

Regards,

Will McGugan
--
http://www.willmcgugan.com

Jan 17 '07 #1
10 2195

Will McGugan wrote:
Hi,

I'd like a generator that takes a sequence and yields tuples containing
n items of the sqeuence, but ignoring the 'odd' items. For example
Forgot to add, for my purposes I will always have a sequence with a
multiple of n items.
Will

Jan 17 '07 #2
Will McGugan wrote:
I'd like a generator that takes a sequence and yields tuples containing
n items of the sqeuence, but ignoring the 'odd' items. For example

take_group(range(9), 3) -(0,1,2) (3,4,5) (6,7,8)
I like
>>items = range(9)
N = 3
zip(*[iter(items)]*N)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

Peter
Jan 17 '07 #3
On 17 Jan 2007 04:50:33 -0800, Will McGugan <wi**@willmcgugan.comwrote:
>
Will McGugan wrote:
Hi,

I'd like a generator that takes a sequence and yields tuples containing
n items of the sqeuence, but ignoring the 'odd' items. For example

Forgot to add, for my purposes I will always have a sequence with a
multiple of n items.
something along the lines of.......
>>[ (x,x+1,x+2) for x in xrange(0,9,3) ]
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
HTH :)
Jan 17 '07 #4
On 2007-01-17, Will McGugan <wi**@willmcgugan.comwrote:
Hi,

I'd like a generator that takes a sequence and yields tuples containing
n items of the sqeuence, but ignoring the 'odd' items. For example

take_group(range(9), 3) -(0,1,2) (3,4,5) (6,7,8)

This is what I came up with..

def take_group(gen, count):
i=iter(gen)
while True:
yield tuple([i.next() for _ in xrange(count)])

Is this the most efficient solution?
This is starting to seem like an FAQ. ;)

The Python library contains a recipe for this in the itertools
recipes in the documentation (5.16.3).

def grouper(n, iterable, padvalue=None):
"grouper(3, 'abcdefg', 'x') --('a','b','c'), ('d','e','f'), ('g','x','x')"
return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

It's more general and cryptic than what you asked for, though.

--
Neil Cerutti
We're not afraid of challenges. It's like we always say: If you want to go out
in the rain, be prepared to get burned. --Brazillian soccer player
Jan 17 '07 #5
Hi!

r=iter(range(9))
print zip(r,r,r)

But, it's few like Peter...
--
Michel Claveau
Jan 17 '07 #6

"Peter Otten" <__*******@web.dewrote in message
news:eo*************@news.t-online.com...
I like
>items = range(9)
N = 3
zip(*[iter(items)]*N)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
Except that it is considered implementation dependent:
http://mail.python.org/pipermail/pyt...ry/307550.html

Alan Isaac
Jan 18 '07 #7
Alan Isaac wrote:
"Peter Otten" <__*******@web.dewrote in message
news:eo*************@news.t-online.com...
>I like
>>items = range(9)
N = 3
zip(*[iter(items)]*N)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

Except that it is considered implementation dependent:
http://mail.python.org/pipermail/pyt...ry/307550.html
Use itertools.izip() then instead of zip(). I think that the occurence of
this idiom on the examples page counts as a blessing :-)

But still, to help my lack of fantasy -- what would a sane zip()
implementation look like that does not guarantee the above output?

Peter

Jan 18 '07 #8
Peter Otten <__*******@web.dewrote:
But still, to help my lack of fantasy -- what would a sane zip()
implementation look like that does not guarantee the above output?
Hypothetically?

The code in zip which builds the result tuples looks (ignoring error
handling) like:

// inside a loop building each result element...
PyObject *next = PyTuple_New(itemsize);

for (j = 0; j < itemsize; j++) {
PyObject *it = PyTuple_GET_ITEM(itlist, j);
PyObject *item = PyIter_Next(it);
PyTuple_SET_ITEM(next, j, item);
}

For fixed size tuples you can create them using PyTuple_Pack. So imagine
some world where the following code works faster for small tuples:

// Outside the loop building the result list:
PyObject *a, *b, *c;
if (itemsize >= 1 && itemsize <= 3) a = PyTuple_GET_ITEM(...);
if (itemsize >= 2 && itemsize <= 3) b = PyTuple_GET_ITEM(...);
if (itemsize == 3) c = PyTuple_GET_ITEM(...);
...

// inside the result list loop:
PyObject *next;
if (itemsize==1) {
next = PyTuple_Pack(1,
PyIter_Next(a));
} else if (itemsize==2) {
next = PyTuple_Pack(2,
PyIter_Next(a),
PyIter_Next(b));
} else if (itemsize==2) {
next = PyTuple_Pack(3,
PyIter_Next(a),
PyIter_Next(b),
PyIter_Next(c));
} else {
next = PyTuple_New(itemsize);

for (j = 0; j < itemsize; j++) {
PyObject *it = PyTuple_GET_ITEM(itlist, j);
PyObject *item = PyIter_Next(it);
PyTuple_SET_ITEM(next, j, item);
}
}

If compiled on a system where the stack grows downwards (as it often does)
the C compiler is very likely to evaluate function arguments in reverse
order.

(BTW, this also assumes that it's an implementation which uses exceptions
or something for error handling otherwise you probably can't get it right,
but maybe something like IronPython could end up with code like this.)

Or maybe if someone added PyTuple_Pack1, PyTuple_Pack2, PyTuple_Pack3
functions which grab their memory off a separate free list for each tuple
length. That might speed up the time to create the tuples as you might be
able to just reset the content not rebuild the object each time. Again that
could make code like the above run more quickly.
Jan 18 '07 #9
Duncan Booth wrote:
Peter Otten <__*******@web.dewrote:
>But still, to help my lack of fantasy -- what would a sane zip()
implementation look like that does not guarantee the above output?
Hypothetically?

The code in zip which builds the result tuples looks (ignoring error
handling) like:

// inside a loop building each result element...
PyObject *next = PyTuple_New(itemsize);

for (j = 0; j < itemsize; j++) {
PyObject *it = PyTuple_GET_ITEM(itlist, j);
PyObject *item = PyIter_Next(it);
PyTuple_SET_ITEM(next, j, item);
}

For fixed size tuples you can create them using PyTuple_Pack. So imagine
some world where the following code works faster for small tuples:

// Outside the loop building the result list:
PyObject *a, *b, *c;
if (itemsize >= 1 && itemsize <= 3) a = PyTuple_GET_ITEM(...);
if (itemsize >= 2 && itemsize <= 3) b = PyTuple_GET_ITEM(...);
if (itemsize == 3) c = PyTuple_GET_ITEM(...);
...

// inside the result list loop:
PyObject *next;
if (itemsize==1) {
next = PyTuple_Pack(1,
PyIter_Next(a));
} else if (itemsize==2) {
next = PyTuple_Pack(2,
PyIter_Next(a),
PyIter_Next(b));
} else if (itemsize==2) {
next = PyTuple_Pack(3,
PyIter_Next(a),
PyIter_Next(b),
PyIter_Next(c));
} else {
next = PyTuple_New(itemsize);

for (j = 0; j < itemsize; j++) {
PyObject *it = PyTuple_GET_ITEM(itlist, j);
PyObject *item = PyIter_Next(it);
PyTuple_SET_ITEM(next, j, item);
}
}

If compiled on a system where the stack grows downwards (as it often does)
the C compiler is very likely to evaluate function arguments in reverse
order.

(BTW, this also assumes that it's an implementation which uses exceptions
or something for error handling otherwise you probably can't get it right,
but maybe something like IronPython could end up with code like this.)

Or maybe if someone added PyTuple_Pack1, PyTuple_Pack2, PyTuple_Pack3
functions which grab their memory off a separate free list for each tuple
length. That might speed up the time to create the tuples as you might be
able to just reset the content not rebuild the object each time. Again
that could make code like the above run more quickly.
Special-casing small tuples meets my sanity criterion :-)

Let's see if I understand the above: In C a call

f(g(), g())

may result in machine code equivalent to either

x = g()
y = g()
f(x, y)

or

y = g()
x = g()
f(x, y)

Is that it?

Peter

Jan 18 '07 #10
Peter Otten <__*******@web.dewrote:
Let's see if I understand the above: In C a call

f(g(), g())

may result in machine code equivalent to either

x = g()
y = g()
f(x, y)

or

y = g()
x = g()
f(x, y)

Is that it?
Yes, or changing one of the calls to h() and compiling with
"cl -Fat.asm -Ox -c t.c":

------ t.c --------
extern int f(int a, int b);
extern int g();
extern int h();

int main(int argc, char **argv) {
return f(g(), h());
}
-------------------

The output file:
------- t.asm -----
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

TITLE t.c
.386P
include listing.inc
if @Version gt 510
..model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

PUBLIC _main
EXTRN _f:NEAR
EXTRN _g:NEAR
EXTRN _h:NEAR
; Function compile flags: /Ogty
_TEXT SEGMENT
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC NEAR
; File c:\temp\t.c
; Line 6
call _h
push eax
call _g
push eax
call _f
add esp, 8
; Line 7
ret 0
_main ENDP
_TEXT ENDS
END
-------------------------
Jan 18 '07 #11

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

Similar topics

10
by: Ivan Voras | last post by:
Are there any performance/size differences between using tuples and using lists? -- -- Every sufficiently advanced magic is indistinguishable from technology - Arthur C Anticlarke
42
by: Jeff Wagner | last post by:
I've spent most of the day playing around with lists and tuples to get a really good grasp on what you can do with them. I am still left with a question and that is, when should you choose a list or...
3
by: mr_vocab | last post by:
hey what is the many dif with them why bothere using tuples and how do you edit a list??? thanks
66
by: Darren Dale | last post by:
Hello, def test(data): i = ? This is the line I have trouble with if i==1: return data else: return data a,b,c,d = test()
3
by: jfj | last post by:
Yo. Why can't we __setitem__ for tuples? The way I see it is that if we enable __setitem__ for tuples there doesn't seem to be any performance penalty if the users don't use it (aka, python...
66
by: Mike Meyer | last post by:
It seems that the distinction between tuples and lists has slowly been fading away. What we call "tuple unpacking" works fine with lists on either side of the assignment, and iterators on the...
9
by: Dr. Colombes | last post by:
I'm looking for a good Python way to generate (enumerate) the 2**N tuples representing all vertices of the unit hypercube in N-dimensional hyperspace. For example, for N=4 the Python code should...
12
by: rshepard | last post by:
I'm a bit embarrassed to have to ask for help on this, but I'm not finding the solution in the docs I have here. Data are assembled for writing to a database table. A representative tuple looks...
122
by: C.L. | last post by:
I was looking for a function or method that would return the index to the first matching element in a list. Coming from a C++ STL background, I thought it might be called "find". My first stop was...
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: 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: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.