443,907 Members | 1,932 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

Iteration over two sequences

 P: n/a I am just starting to learn Python, mostly by going through the examples in Dive Into Python and by playing around. Quite frequently, I find the need to iterate over two sequences at the same time, and I have a bit of a hard time finding a way to do this in a "pythonic" fashion. One example is a dot product. The straight-ahead C-like way of doing it would be: def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psum However, the range(len(a)) term is awfully un-pythonic :) The built-in function map() gives me a way of "transposing" the a list and the b list, and now I can handle it with a list comprehension: def dotproduct(a, b): return sum([x*y for x, y in map(None, a, b)]) My concern is one of efficiency: it seems to me that I have two loops there: first one implied with map(...) and then the for loop -- which seems like a waste since I feel I should be able to do the multiplication via an argument to map. So far I have come up with an alternative via defining a separate function: def dotproduct(a, b): def prod(x,y): return x*y return sum(map(prod, a, b)) I suppose I could also use a lambda here -- but is there a different, efficient, and obvious solution that I'm overlooking? Thanks, Henrik -- "On some great and glorious day the plain folks of the land will reach in their heart's desire at last and the White House will be adorned by a downright moron." -H.L. Mencken (1880-1956) American Writer Jul 18 '05 #1
14 Replies

 P: n/a zip or izip is your friend: import itertools a = [1,2,3] b = ['a', 'b', 'c'] for a,b in itertools.izip(a, b): print a, b -- Regards, Diez B. Roggisch Jul 18 '05 #2

 P: n/a "Henrik Holm" wrote in message news:1gq9qs9.3snutr1s4mcn2N%ne*******@henrikholm.c om... I am just starting to learn Python, mostly by going through the examples in Dive Into Python and by playing around. Quite frequently, I find the need to iterate over two sequences at the same time, and I have a bit of a hard time finding a way to do this in a "pythonic" fashion. One example is a dot product. The straight-ahead C-like way of doing it would be: def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psum However, the range(len(a)) term is awfully un-pythonic :) The built-in function map() gives me a way of "transposing" the a list and the b list, and now I can handle it with a list comprehension: def dotproduct(a, b): return sum([x*y for x, y in map(None, a, b)]) My concern is one of efficiency: it seems to me that I have two loops there: first one implied with map(...) and then the for loop -- which seems like a waste since I feel I should be able to do the multiplication via an argument to map. So far I have come up with an alternative via defining a separate function: def dotproduct(a, b): def prod(x,y): return x*y return sum(map(prod, a, b)) I suppose I could also use a lambda here -- but is there a different, efficient, and obvious solution that I'm overlooking? Thanks, Henrik -- "On some great and glorious day the plain folks of the land will reach in their heart's desire at last and the White House will be adorned by a downright moron." -H.L. Mencken (1880-1956) American Writer zip maybe? def dotproduct(a,b): return sum([x*y for x,y in zip(a,b)]) -- Paul Jul 18 '05 #3

 P: n/a "Henrik Holm" wrote in message news:1gq9qs9.3snutr1s4mcn2N%ne*******@henrikholm.c om... I suppose I could also use a lambda here -- but is there a different, efficient, and obvious solution that I'm overlooking? Check the itertools recipes in the library documentation. Jul 18 '05 #4

 P: n/a Richard Brodie wrote: "Henrik Holm" wrote in message news:1gq9qs9.3snutr1s4mcn2N%ne*******@henrikholm.c om... I suppose I could also use a lambda here -- but is there a different, efficient, and obvious solution that I'm overlooking? Check the itertools recipes in the library documentation. Thanks, the itertools seem to contain several useful functions. -- "On some great and glorious day the plain folks of the land will reach in their heart's desire at last and the White House will be adorned by a downright moron." -H.L. Mencken (1880-1956) American Writer Jul 18 '05 #5

 P: n/a > Quite frequently, I find the need to iterate over two sequences at the same time, and I have a bit of a hard time finding a way to do this in a "pythonic" fashion. One example is a dot product. The straight-ahead C-like way of doing it would be: def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psum for this particular example, the most pythonic way is to do nothing at all, or, if you must call it dotproduct, from Numeric import dot as dotproduct Jul 18 '05 #6

 P: n/a I tried this and I got: [(1, 'a'), (2, 'b'), (3, 'c')] But if I change: a=[1,2] I got: [(1, 'c')] Why is that? I thought I should be getting: [(1, 'a'),(2,'b')] ????? "Diez B. Roggisch" wrote in message news:34*************@individual.net... zip or izip is your friend: import itertools a = [1,2,3] b = ['a', 'b', 'c'] for a,b in itertools.izip(a, b): print a, b -- Regards, Diez B. Roggisch Jul 18 '05 #7

 P: n/a John Lenton wrote: def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psum for this particular example, the most pythonic way is to do nothing at all, or, if you must call it dotproduct, from Numeric import dot as dotproduct Downloading, installing, and getting to know numerical modules for Python is mext on my list :). However, I was under the impression that Numarray is preferred to Numeric -- is that correct? Are these two competing packages? (Hopefully this is not flame war bait...) -- "On some great and glorious day the plain folks of the land will reach in their heart's desire at last and the White House will be adorned by a downright moron." -H.L. Mencken (1880-1956) American Writer Jul 18 '05 #8

 P: n/a Henrik Holm wrote: John Lenton wrote:def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psumfor this particular example, the most pythonic way is to do nothing atall, or, if you must call it dotproduct,>from Numeric import dot as dotproduct Downloading, installing, and getting to know numerical modules for Python is mext on my list :). However, I was under the impression that Numarray is preferred to Numeric -- is that correct? Are these two competing packages? (Hopefully this is not flame war bait...) Numarray is the replacement for Numeric. Some people are still using Numeric for a variety of reasons, e.g. they use a package that has not been updated to use numarray, they can't afford the performance penalty that numarray has for small arrays, etc. Steve Jul 18 '05 #9

 P: n/a > Downloading, installing, and getting to know numerical modules for Python is mext on my list :). However, I was under the impression that Numarray is preferred to Numeric -- is that correct? Are these two competing packages? (Hopefully this is not flame war bait...) Numeric's dot uses, if the appropriate libraries are installed, processor-tuned code (it tries to load blas, and an attempt to load blas will load atlas if present). Last time I checked numarray did not, and so Numeric's dot is (or was) faster than numarray's dot by an order of magnitude (and more, as the size of the array grew). Jul 18 '05 #10

 P: n/a Henrik Holm wrote: John Lenton wrote:def dotproduct(a, b): psum = 0 for i in range(len(a)): psum += a[i]*b[i] return psumfor this particular example, the most pythonic way is to do nothing atall, or, if you must call it dotproduct,>from Numeric import dot as dotproduct Downloading, installing, and getting to know numerical modules for Python is mext on my list :). However, I was under the impression that Numarray is preferred to Numeric -- is that correct? Are these two competing packages? (Hopefully this is not flame war bait...) Numarray is the future, Numeric is the "past", but in the present Numeric is better (and more mature) at some stuff than Numarray. Learning both is not much harder than learning one, actually (they share a lot). --Scott David Daniels Sc***********@Acm.Org Jul 18 '05 #11

 P: n/a "It's me" wrote in message news:Mr*****************@newssvr21.news.prodigy.co m...I tried this and I got: [(1, 'a'), (2, 'b'), (3, 'c')] But if I change: a=[1,2] I got: [(1, 'c')] Why is that? I thought I should be getting: [(1, 'a'),(2,'b')] ????? Cut and paste the actual input and output for an interactive session with a freshly started interpreter and perhaps we can answer for sure. Terry J. Reedy Jul 18 '05 #12

 P: n/a My example is somewhat flawed because it assigns a and b the values of the iteration - so in the end, b is 'c', and only setting a to [1,2] will show your results. Use c and d for the variables in the for-statments, and things work as expected. -- Regards, Diez B. Roggisch Jul 18 '05 #13

 P: n/a "Scott David Daniels" wrote in message news:41********@nntp0.pdx.net: Numarray is the future, Numeric is the "past", This statement is not obviously true. See the recent discussion on the developer lists. (Search for Numeric3.) Alan Isaac Jul 18 '05 #14

 P: n/a David Isaac wrote: "Scott David Daniels" wrote in message news:41********@nntp0.pdx.net:Numarray is the future, Numeric is the "past", This statement is not obviously true. See the recent discussion on the developer lists. (Search for Numeric3.) Alan Isaac I stand corrected. Sorry to have conveyed a mis-impression that I have held for a while. It was my understanding that the Numeric code was so hard to maintain that our fearless leader would never let it in the codebase. Hence, Numarray was born. A quick look through some of the Numeric3 messages leaves me with the impression that Numeric3 will be more of a rebirth than a small change. I have used Numeric for several big projects (that died for commercial, rather than technical, reasons), and have certainly appreciated it. The thrust of my comment holds, however, "learning both is not much harder than learning one." --Scott David Daniels Sc***********@Acm.Org Jul 18 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.