Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiple variables in a for loop in Python

I am trying to get a deeper understanding to how for loops for different data types in Python. The simplest way of using a for loop an iterating over an array is as

for i in range(len(array)):
    do_something(array[i])

I also know that I can

for i in array:
    do_something(i)

What I would like to know is what this does

for i, j in range(len(array)):
    # What is i and j here?

or

for i, j in array:
    # What is i and j in this case?

And what happens if I try using this same idea with dictionaries or tuples?

like image 632
Ely Fialkoff Avatar asked Aug 20 '18 15:08

Ely Fialkoff


3 Answers

The simplest and best way is the second one, not the first one!

for i in array:
    do_something(i)

Never do this, it's needlessly complicating the code:

for i in range(len(array)):
    do_something(array[i])

If you need the index in the array 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)):
    # What is i and j here?

This one might work, assumes the array is "two-dimensional":

for i, j in array:
    # What is i and j in this case?

An example of a two-dimensional array would be a list of pairs:

>>> for i, j in [(0, 1), ('a', 'b')]:
...     print('i:', i, 'j:', j)
...     
i: 0 j: 1
i: a j: b

Note: ['these', 'structures'] are called lists in Python, not arrays.

like image 75
wim Avatar answered Oct 12 '22 17:10

wim


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
    ...
like image 7
modesitt Avatar answered Oct 12 '22 16:10

modesitt


Python's for loop is an iterator-based loop (that's why bruno desthuilliers says that it "works for all iterables (lists, tuples, sets, dicts, iterators, generators etc)". A string is also another common type of iterable).

Let's say you have a list of tuples. Using that nomenclature you shared, one can iterate through both the keys and values simultaneously. For instance:

tuple_list = [(1, "Countries, Cities and Villages"),(2,"Animals"),(3, "Objects")]

for k, v in tuple_list:
    print(k, v)

will give you the output:

1 Countries, Cities and Villages
2 Animals
3 Objects

If you use a dictionary, you'll also gonna be able to do this. The difference here is the need for .items()

dictionary = {1: "Countries, Cities and Villages", 2: "Animals", 3: "Objects"}

for k, v in dictionary.items():
    print(k, v)

The difference between dictionary and dictionary.items() is the following

dictionary: {1: 'Countries, Cities and Villages', 2: 'Animals', 3: 'Objects'}
dictionary.items(): dict_items([(1, 'Countries, Cities and Villages'), (2, 'Animals'), (3, 'Objects')])

Using dictionary.items() we'll get a view object containig the key-value pairs of the dictionary, as tuples in a list. In other words, with dictionary.items() you'll also get a list of tuples. If you don't use it, you'll get

TypeError: cannot unpack non-iterable int object

If you want to get the same output using a simple list, you'll have to use something like enumerate()

list = ["Countries, Cities and Villages","Animals", "Objects"]

for k, v in enumerate(list, 1): # 1 means that I want to start from 1 instead of 0
    print(k, v)

If you don't, you'll get

ValueError: too many values to unpack (expected 2)

So, this naturally raises the question... do I need always a list of tuples? No. Using enumerate() we'll get an enumerate object.

like image 4
Tiago Martins Peres Avatar answered Oct 12 '22 16:10

Tiago Martins Peres