If you want the effect of a nested for loop, use:
import itertools
for i, j in itertools.product(range(x), range(y)):
# Stuff...
If you just want to loop simultaneously, use:
for i, j in zip(range(x), range(y)):
# Stuff...
Note that if x and y are not the same length, zip will truncate to the shortest list. As @abarnert pointed out, if you don't want to truncate to the shortest list, you could use itertools.zip_longest.
UPDATE
Based on the request for "a function that will read lists "t1" and "t2" and return all elements that are identical", I don't think the OP wants zip or product. I think they want a set:
def equal_elements(t1, t2):
return list(set(t1).intersection(set(t2)))
# You could also do
# return list(set(t1) & set(t2))
The intersection method of a set will return all the elements common to it and another set (Note that if your lists contains other lists, you might want to convert the inner lists to tuples first so that they are hashable; otherwise the call to set will fail.). The list function then turns the set back into a list.
UPDATE 2
OR, the OP might want elements that are identical in the same position in the lists. In this case, zip would be most appropriate, and the fact that it truncates to the shortest list is what you would want (since it is impossible for there to be the same element at index 9 when one of the lists is only 5 elements long). If that is what you want, go with this:
def equal_elements(t1, t2):
return [x for x, y in zip(t1, t2) if x == y]
This will return a list containing only the elements that are the same and in the same position in the lists.
Answer from SethMMorton on Stack Overflow
I'm a Python beginner and wondering if anyone can explain what the for j in range i line is doing here? In addition, what is the proper name for these i and j expressions?
n=5;
for i in range(n):
for j in range(i):
print ('* ', end="")
print('')
for i in range(n,0,-1):
for j in range(i):
print('* ', end="")
print('')for loop - python newbie: for j in range - Stack Overflow
arrays - Using multiple variables in a for loop in Python - Stack Overflow
"for i in range()" to do an infinite loop with a counter - Ideas - Discussions on Python.org
python
for i in range(5, 0, -1):
for j in range(1, i + 1):
print(j, end="")
print()
If you want the effect of a nested for loop, use:
import itertools
for i, j in itertools.product(range(x), range(y)):
# Stuff...
If you just want to loop simultaneously, use:
for i, j in zip(range(x), range(y)):
# Stuff...
Note that if x and y are not the same length, zip will truncate to the shortest list. As @abarnert pointed out, if you don't want to truncate to the shortest list, you could use itertools.zip_longest.
UPDATE
Based on the request for "a function that will read lists "t1" and "t2" and return all elements that are identical", I don't think the OP wants zip or product. I think they want a set:
def equal_elements(t1, t2):
return list(set(t1).intersection(set(t2)))
# You could also do
# return list(set(t1) & set(t2))
The intersection method of a set will return all the elements common to it and another set (Note that if your lists contains other lists, you might want to convert the inner lists to tuples first so that they are hashable; otherwise the call to set will fail.). The list function then turns the set back into a list.
UPDATE 2
OR, the OP might want elements that are identical in the same position in the lists. In this case, zip would be most appropriate, and the fact that it truncates to the shortest list is what you would want (since it is impossible for there to be the same element at index 9 when one of the lists is only 5 elements long). If that is what you want, go with this:
def equal_elements(t1, t2):
return [x for x, y in zip(t1, t2) if x == y]
This will return a list containing only the elements that are the same and in the same position in the lists.
There's two possible questions here: how can you iterate over those variables simultaneously, or how can you loop over their combination.
Fortunately, there's simple answers to both. First case, you want to use zip.
x = [1, 2, 3]
y = [4, 5, 6]
for i, j in zip(x, y):
print(str(i) + " / " + str(j))
will output
1 / 4
2 / 5
3 / 6
Remember that you can put any iterable in zip, so you could just as easily write your exmple like:
for i, j in zip(range(x), range(y)):
# do work here.
Actually, just realised that won't work. It would only iterate until the smaller range ran out. In which case, it sounds like you want to iterate over the combination of loops.
In the other case, you just want a nested loop.
for i in x:
for j in y:
print(str(i) + " / " + str(j))
gives you
1 / 4
1 / 5
1 / 6
2 / 4
2 / 5
...
You can also do this as a list comprehension.
[str(i) + " / " + str(j) for i in range(x) for j in range(y)]
I think @csevier added a reasonable discussion about your first question, but I'm not sure the second question is answered as clearly for you based on your comments so I'm going to try a different angle.
Let's say you did:
for x in range(10):
print(x)
That's reasonably understandable - you created a list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] and you printed each of the values in that list in-turn. Now let's say that we wanted to just print "hello" 10 times; well we could modify our existing code very simply:
for x in range(10):
print(x)
print('hello')
Umm, but now the x is messing up our output. There isn't a:
do this 10 times:
print('hello')
syntax. We could use a while loop but that means defining an extra counter:
loop_count = 0
while loop_count < 10:
print('hello')
loop_count += 1
That's baggage. So, the better way would be just to use for x in range(10): and just not bother doing print(x); the value is there to make our loop work, not because it's actually useful in any other way. This is the same for j (though I've used x in my examples because I think you're more likely to encounter it in tutorials, but you could use almost any name you want). Also, while loops are generally used for loops that can run indefinitely, not for iterating over an object with fixed size: see here.
Welcome to the python community! This is a great question. In python, as in other languages, there are many ways to do things. But when you follow a convention that the python community does, that is often referred to as a "pythonic" solution. The method print_progression is a common pythonic solution to iteration of a user defined data structure. In the case above, lets explain first how the code works and then why we would do it that way.
Your print_progression method takes advantage of the fact that your Progression class implements the iteration protocol by implementing the next and iter dunder/magic methods. Because those are implemented you can iterate your class instance both internally as next(self) has done, and externally next(Progression()) which is the exactly what you were getting at with you number 1. Because this protocol is implemented already, this class can by used in any builtin iterator and generator context for any client! Thats a polymorphic solution. Its just used internally as well because you don't need to do it in 2 different ways.
Now for the unused J variable. They are just using that so they can use the for loop. Just using range(n) would just return an itterable but not iterate over it. I dont quite agree with the authors use of the variable named J, its often more common to denote an unused variable that is just used because it needs to be as a single underscore. I like this a little better:
print(' '.join(str(next(self)) for _ in range(n)))
The simplest and best way is the second one, not the first one!
for i in array:
do_something(i)
Never iterate indices just to index the container, it's needlessly complicating the code:
for i in range(len(array)):
do_something(array[i])
If you need the index for some reason (usually you don't), then do this instead:
for i, element in enumerate(array):
print("working with index", i)
do_something(element)
This is just an error, you will get TypeError: 'int' object is not iterable when trying to unpack one integer into two names:
for i, j in range(len(array)):
...
This one might work, assumes the array is "two-dimensional":
for i, j in array:
...
An example of a two-dimensional array is a list of pairs:
>>> for i, j in [(0, 1), ('a', 'b')]:
... print(f"{i=} {j=}")
...
i=0 j=1
i='a' j='b'
Note: ['these', 'structures'] are called lists in Python, not arrays.
Your third loop will not work as it will throw a TypeError for an int not being iterable. This is because you are trying to "unpack" the int that is the array's index into i, and j which is not possible. An example of unpacking is like so:
tup = (1,2)
a,b = tup
where you assign a to be the first value in the tuple and b to be the second. This is also useful when you may have a function return a tuple of values and you want to unpack them immediately when calling the function. Like,
train_X, train_Y, validate_X, validate_Y = make_data(data)
More common loop cases that I believe you are referring to is how to iterate over an arrays items and it's index.
for i, e in enumerate(array):
...
and
for k,v in d.items():
...
when iterating over the items in a dictionary. Furthermore, if you have two lists, l1 and l2 you can iterate over both of the contents like so
for e1, e2 in zip(l1,l2):
...
Note that this will truncate the longer list in the case of unequal lengths while iterating. Or say that you have a lists of lists where the outer lists are of length m and the inner of length n and you would rather iterate over the elements in the inner lits grouped together by index. This is effectively iterating over the transpose of the matrix, you can use zip to perform this operation as well.
for inner_joined in zip(*matrix): # will run m times
# len(inner_joined) == m
...