Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Loops for simultaneous operation, Two or possibly more?

This question closely relates to How do I run two python loops concurrently?

I'll put it in a clearer manner: I get what the questioner asks in the above link, something like

for i in [1,2,3], j in [3,2,1]:
    print i,j
    cmp(i,j) #do_something(i,j)

But

L1: for i in [1,2,3] and j in [3,2,1]: doesnt work

Q1. but this was amusing what happened here:

    for i in [1,2,3], j in [3,2,1]:
    print i,j


[1, 2, 3] 0
False 0

Q2. How do I make something like L1 work?

Not Multithreading or parallelism really. (It's two concurrent tasks not a loop inside a loop) and then compare the result of the two.

Here the lists were numbers. My case is not numbers:

for i in f_iterate1() and j in f_iterate2():

UPDATE: abarnert below was right, I had j defined somewhere. So now it is:

>>> for i in [1,2,3], j in [3,2,1]:
    print i,j



Traceback (most recent call last):
  File "<pyshell#142>", line 1, in <module>
    for i in [1,2,3], j in [3,2,1]:
NameError: name 'j' is not defined

And I am not looking to zip two iteration functions! But process them simultaneously in a for loop like situation. and the question still remains how can it be achieved in python.

UPDATE #2: Solved for same length lists

>>> def a(num):
    for x in num:
        yield x


>>> n1=[1,2,3,4]
>>> n2=[3,4,5,6]
>>> x1=a(n1)
>>> x2=a(n2)
>>> for i,j in zip(x1,x2):
    print i,j


1 3
2 4
3 5
4 6
>>> 

[Solved]

Q3. What if n3=[3,4,5,6,7,8,78,34] which is greater than both n1,n2. zip wont work here.something like izip_longest? izip_longest works good enough.

like image 866
user2290820 Avatar asked May 14 '13 20:05

user2290820


People also ask

Can we use two for loops simultaneously?

So, we can write two for loops in a code and it is called as nested for loop. But first for loop executes then goes to second for loop.

Can we use 2 variables in for loop Python?

Using for loop with two variables with enumerate(). In Python, the enumerate() function is used to return the index along with the element used for the loop in an iterable. Here, we can iterate two variables in for loop with iterators.

How do you make multiple loops in Python?

Summary: To write a nested for loop in a single line of Python code, use the one-liner code [print(x, y) for x in iter1 for y in iter2] that iterates over all values x in the first iterable and all values y in the second iterable.


3 Answers

It's hard to understand what you're asking, but I think you just want zip:

for i, j in zip([1,2,3], [3,2,1]):
    print i, j

for i, j in zip(f_iterate1(), f_iterate2()):
    print i, j

And so on…

This doesn't do anything concurrently as the term is normally used, it just does one thing at a time, but that one thing is "iterate over two sequences in lock-step".


Note that this extends in the obvious way to three or more lists:

for i, j, k in zip([1,2,3], [3,2,1], [13, 22, 31]):
    print i, j, k

(If you don't even know how many lists you have, see the comments.)


In case you're wondering what's going on with this:

for i in [1,2,3], j in [3,2,1]:
    print i,j

Try this:

print [1,2,3], j in [3,2,1]

If you've already defined j somewhere, it will print either [1, 2, 3] False or [1, 2, 3] True. Otherwise, you'll get a NameError. That's because you're just creating a tuple of two values, the first being the list [1,2,3], and the second being the result of the expression j in [3,2,1].

So:

j=0
for i in [1,2,3], j in [3,2 1]:
    print i, j

… is equivalent to:

j=0
for i in ([1,2,3], False):
    print i, 0

… which will print:

[1, 2, 3] 0
False 0
like image 133
abarnert Avatar answered Sep 25 '22 13:09

abarnert


You want to use the zip() function:

for i, j in zip([1, 2, 3], [3, 2, 1]):
    #

for i, j in zip(f_iterate1(), f_iterate2()):
    #

zip() pairs up the elements of the input lists, letting you process them together.

If your inputs are large or are iterators, use future_builtins.zip(), or, if you don't care about forward compatibility with Python 3, use itertools.izip() instead; these yield pairs on demand instead of creating a whole output list in one go:

from future_builtins import zip

for i, j in zip(f_iterate1(), f_iterate2()):

Your generators fall in this scenario.

Last but not least, if your input lists have different lengths, zip() stops when the shortest list is exhausted. If you want to continue with the longest list instead, use itertools.izip_longest(); it'll use a fill value when the shorter input sequence(s) are exhausted:

>>> for i, j, k in izip_longest(range(3), range(3, 5), range(5, 10), fillvalue=42):
...     print i, j, k
... 
0 3 5
1 4 6
2 42 7
42 42 8
42 42 9

The default for fillvalue is None.


Your attempt:

for i in [1,2,3], j in [3,2,1]:

is really interpreted as:

for i in ([1,2,3], j in [3,2,1]):

where the latter part is interpreted as a tuple with two values, one a list, the other a boolean; after testing j in [3,2,1], is either True or False. You had j defined as 0 from a previous loop experiment and thus 0 in [3, 2, 1] is False.

like image 45
Martijn Pieters Avatar answered Sep 26 '22 13:09

Martijn Pieters


For same-length arrays, you can use the index to refer to corresponding locations in respective lists, like so:

a = [1, 2, 3, 4, 5]
b = [2, 4, 6, 8, 10]
for i in range(len(a)):
    print(a[i])
    print(b[i])

This accesses same indices of both lists at the same time.

like image 39
AppB Avatar answered Sep 25 '22 13:09

AppB