Iterating over a list in python using for-loop

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Iterating over a list in python using for-loop



I have a question about iterating over a list in python.
Let's say I have a list: row = ['1', '2', '3'] and want to convert its element to integers, so that: row = [1, 2, 3].


row = ['1', '2', '3']


row = [1, 2, 3]



I know I can do it with list comprehension:


row = [int(i) for i in row]



or for-loop:


for i in range(len(row)):
row[i] = int(row[i])



My question concerns range(len(row)) part. Can someone answer in layman friendly way, why I can do something like this:


range(len(row))


for i in row:
print(i)



But I can't do this:


for i in row:
row[i] = int(row[i])





Try running ['1', '2']['1'] in the interpreter. Can you use strings as lists' indices?
– ForceBru
Aug 8 at 14:12


['1', '2']['1']





this will help anandology.com/python-practice-book/iterators.html
– JanaTii
Aug 8 at 14:25





Thanks, now I understand. I thought that for i works on indexes, so it goes from first to last element, without getting its value, just like in list comprehension.
– mykoza
Aug 8 at 15:35


for i





i is just an arbitrary variable name, it doesn't affect what's going on. You can call it banana and it all works the same.
– juanpa.arrivillaga
Aug 8 at 15:43


i


banana





@juanpa.arrivillaga What I meant is that in for-loop, that variable i or banana takes values of list elements, so if list is ['3',1'','2'], first i would have value of 3, but in list comprehension which uses same for i in first i is 0
– mykoza
Aug 8 at 15:51


i


banana


['3',1'','2']


i


3


for i in


i


0




4 Answers
4



When you do for i in row, i takes the values in row, i.e. '1', then '2', then '3'.


for i in row


i


row


'1'


'2'


'3'



Those are strings, which are not valid as a list index. A list index should be an integer. When doing range(len(row)) you loop on integers up to the size of the list.


range(len(row))



By the way, a better approach is:


for elt_id, elt in enumerate(list):
# do stuff





In addition, even if converted, an index out of range error would throw due to the first val not being 0.
– dfundako
Aug 8 at 14:14





@dfundako Yeah the conversion is not a good idea, especially since it could work because of its example with values which could be indexes, but it could also be something else...
– Mathieu
Aug 8 at 14:15





Can you explain for elt_id, elt in enumerate(list):? What are elt_id, elt?
– Gigaflop
Aug 8 at 14:26


for elt_id, elt in enumerate(list):


elt_id, elt





@Gigaflop Doing for i in range(len(list)): is bad practice. A better way is to use enumerate() which will return a tuple (id, elt). Thus using enumerate, you get both the id and the element at each iteration. It is equivalent to: for id in range(len(list)): elt = list[id]
– Mathieu
Aug 8 at 14:28


for i in range(len(list)):


enumerate()


(id, elt)


for id in range(len(list)): elt = list[id]





@mykoza It is better that using range(len(list)) but it also uses a for loop. And it can be incorporated in a list comprehension. You have 3 scenarios: 1 you need to iterate on the element in the list, then simply use for elt in list:, 2 you only need the indexes, 3 you will need the indexes and the element. For these 2 last, it's better to use an enumerate than a range(len(list))
– Mathieu
Aug 8 at 14:46


range(len(list))


for elt in list:


enumerate


range(len(list))



Here's an example from IDLE:


>>> row = ['1', '2', '3']
>>> for i in row:
row[i] = int(row[i])

Traceback (most recent call last):
File "<pyshell#3>", line 2, in <module>
row[i] = int(row[i])
TypeError: list indices must be integers or slices, not str



The items being iterated over are not integers, and cannot be used as an index to the list.



The following will work for some of the time, but throw an IndexError at the end:


IndexError


for i in row:
i2 = int(i)
row[i2] = i2



Given row = ['1', '2', '3'], each item inside row is a string, thus it can be easily printed:


row = ['1', '2', '3']


for i in row:
print(i)



However, in your second example you are trying to access row using a string. You need an integer to access values inside a list, and row is a list! (of strings, but a list still).


for i in row:
# row[i] = int(row[i]) -> this will throw an error
row[int(i)] = int(row[int(i)]) # this will throw an error



When you do


for i in row:
row[i] = int(row[int(i)])



i is the element in the array row. Therefore, i will be '1' then '2' then '3'.


row


i



But indexes have to be integers and i is a string so there will be an error.



If you do:


for i in row:
row[int(i)] = int(row[i])



It will still be an error because i is the integer of element in the array row. Therefore, i will be 1 then 2 then 3.


row



But row[3] will cause a IndexError because there are only 3 elements in the list and numbering starts from 0.


row[3]


IndexError



While in the other case(the first case), i becomes 0 then 1 then 2 which does not cause an error because row[2] is valid.


i



The reason is :



range() is 0-index based, meaning list indexes start at 0, not 1. eg.
The syntax to access the first element of a list is mylist[0] .
Therefore the last integer generated by range() is up to, but not
including, stop .





Thanks, for your answer! Can you tell me why in seemingly same construct: for i in row, there are two different ways of handling the i? What I mean is that in loop, i takes values from list, but in list comprehension it starts from 0?
– mykoza
Aug 8 at 15:26


for i in row


i


i





@mykoza see edit
– Agile_Eagle
Aug 8 at 15:45





Thank you for elaborating, but I didn't mean range() function. What I was saying was that in list comprehension [sth for i in list], i starts from 0, but in loop for i in list: sth, i takes the value of list element
– mykoza
Aug 8 at 16:00



range()


[sth for i in list]


i


for i in list: sth


i


list





@mykoza row = [int(i) for i in row] also starts i from 1 upto 3(which are the elements of the list) but it creates a new list named row which has int(i) where i is every element in the list row. So the new list becomes row = [int("1"), int("2"), int("3")]
– Agile_Eagle
Aug 8 at 16:05



row = [int(i) for i in row]


int(i)


row = [int("1"), int("2"), int("3")]





Alright thanks, I get it now.
– mykoza
Aug 8 at 16:17






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard