element modification during python list iteration [duplicate] - python

This question already has answers here:
Change value of currently iterated element in list
(3 answers)
Scope of python variable in for loop
(10 answers)
Closed 4 years ago.
Could anyone, please, explain what exactly happens in the following code to the "element" during iteration?
array = [2,3,4]
for element in array:
element = 3
print(array)
>>>[2, 3, 4]
Output is [2, 3, 4]
instead of [3, 3, 3]
Did I understand it correctly that when using "for element in l" syntax, we can only reference but not modify each element of an array of what does happen here?
P.S. I've seen the question named "why shouldn't you iterate like 'for element in array' ", but I couldn't find that one, so I asked it in this way. Seems like I found one of the disadvantages of iterating in this way. Please, redirect me to the mentioned question if possible.

Explanation
In the above example any changes to variable element in the loop is not possible.
Code
To get your expected output try this:
array = [2,3,4]
for i in range(len(array)):
array[i] = 3
print(array)

When the iteration start element variable already has the current value in the array. when you assign 3 to it it will contain it until the next iteration when it will again take the current value of the array and so on.
To get [3, 3, 3] you need to do it as the following:
array = [2,3,4]
for i in range(0,len(array)):
array[i]=3
print(array)

That's because element is a local variable in the scope of the for loop.
Run this snippet. I hope it can be self-explanatory (I used e instead of element), also I used enumerate to get the index:
array = [2,3,4]
for i, e in enumerate(array):
print('i =', i, 'e =', e)
e = 100
print('e = 100-->','e =', e, 'but array[i]=',array[i])
array[i] = e
print('array[i] = e --> array[i]=',array[i])
print('-'*10)
print(array) #=> [100,100,100]
Quick explanation
e and i are local variables which receive the value of the element and the index of the array at each iteration.
Inside the loop you can change the value of e but it doesn't affect the the array. To change the value inside the array it is required to access it by index (array[i]).

Related

Python for loop weird bug [duplicate]

This question already has answers here:
Why can I use a list index as an indexing variable in a for loop? [duplicate]
(6 answers)
Are for-loop name list expressions legal?
(2 answers)
Closed last year.
So in a quiz, I have given the question what the execution of this block of code gives (The one under).
a = [0, 1, 2, 3]
for a[0] in a:
print(a[0])
I had selected error but to my surprise, it actually works and is able to print all the elements inside the list. But how?
firstly the element getting variable (usually i) is shadowing the actual variable on top of that we are getting the first element inside a number so how is it working.
a[0] is type of a so it can be used to iterate over the array but as in look you are assigning value in a[0] it's value will change to last element of the array.
a = [0,1,2,3]
for a[0] in a:
print(a[0]
Will result in:
0
1
2
3
But now printing a will give you modified array:
print(a)
[3, 1, 2, 3]

For loop is not executing as expected, sequence matters so can't use set() here [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 4 years ago.
I used a for loop to remove the duplicates in a list from the left side. For example, [3,4,4,3,6,3] should be [4,6,3]. And also the sequence cannot be changed, that's why I cannot use a set here. If I use set() here, the result would be [3,4,6].
def solve(arr):
for i in arr:
if i in arr[arr.index(i)+1:]:
arr.remove(i)
return arr
solve([1,2,1,2,1,2,3])
It should return [1,2,3]. Instead, I got [2,1,2,3]. I viewed the visualized execution of the code, and it seems when python got to the item '2' the second time, meaning when the arr is mutated to be [2,1,2,3], it just suddenly stopped iteration from the for loop and returned the list as it is. When it should detect there is still another '2' in the list. Please help
You can use set for this:
a = [1,2,1,2,1,2,3]
b = set(a)
Then b will be:
{1,2,3}
You can try this way:
def solve(arr):
another_arr = []
for i in arr:
if i in another_arr:
another_arr.remove(i)
another_arr.append(i)
else:
another_arr.append(i)
return another_arr
print(solve([1, 2, 1, 2, 1, 2, 3]))

Why doesn`t list[:][0] get me the first row of the list? [duplicate]

This question already has answers here:
Understanding slicing
(38 answers)
Closed 6 years ago.
For the following:
list=[[2, 3, 5], [7, 8, 9]]
Why does [list[0][0], list[1][0]] represent the first row ([2, 7]), but the command list[:][0] or list[0:2][0] returns the first column ([2, 3, 5])?
The way I see it list[:][0] should get all the possible values for the first parameter (that is 0 and 1) and 0 for the second, meaning it would return the first row. Instead what it does is return the first column and I can't understand why.
In python, the [a:b:c] syntax creates a new list. That is,
list = [1,2,3]
print(list[:])
is going to print a list, not a value.
Therefore, when you say list[:][0] you are making a copy of the original list (list[:]) and then accessing item 0 within it.
Of course you know, item 0 of the original list (list[0]) is another list.
I think you want:
[sl[0] for sl in list]
Elaboration:
This is called a "comprehension." It is a compact special syntax for generating lists, dicts, and tuples by processing or filtering other iterables. Basically {..}, [..], and (..) with an expression inside involving a for and optionally an if. Naturally, you can have multiples (like [x for x in y for y in z]) of the for, and multiples of the if.
In your case, it's pretty obvious you want a list. So []. You want to make the list by taking the first item from each sublist. So [sl[0] for sl in list].
Here's a more-detailed article: http://carlgroner.me/Python/2011/11/09/An-Introduction-to-List-Comprehensions-in-Python.html

How does this for loop is work? [duplicate]

This question already has answers here:
for loops and iterating through lists - how does "for a[-1] in a:" work?
(3 answers)
Closed 6 years ago.
Please let me know how this for loop is working.
b= [4,5,6]
for b[-1] in b:
print(b[-1])
This code snippet is giving me output as:-
4
5
5
I checked it with Python 2.7
Each iteration, element i of b is picked. It is attributed to b[-1] (last element of b) and printed. So each step, the last element of b (6 before the loop) is attributed the value of the ith element.
Eventually, at the last iteration, the ith value is read and the value read is the value that was written the iteration before (that is, 5).
Modify the code to print b at each step and it becomes obvious:
b = [4,5,6]
for b[-1] in b:
print(b[-1])
print(b)
(Don't do this kind of things in real life.)
You can understand it while printing the whole b list:
b= [4,5,6]
for b[-1] in b:
print(b)
print(b[-1])
Output
[4, 5, 4] # first iteration, you set last element(6) with first element(4) [4,5,6] -> [4,5,4]
4
[4, 5, 5] # second iteration, you set last element(4) with element(5), [4,5,4] -> [4,5,5]
5
[4, 5, 5] # last iteration, you set last element(5) with element(5), no change
5
So basically every iteration your last element becomes the element you iterate with.

Basic python: how to increase value of item in list [duplicate]

This question already has answers here:
Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add (append) elements to a list?
(9 answers)
Closed 4 months ago.
This is such a simple issue that I don't know what I'm doing wrong. Basically I want to iterate through the items in an empty list and increase each one according to some criteria. This is an example of what I'm trying to do:
list1 = []
for i in range(5):
list1[i] = list1[i] + 2*i
This fails with an list index out of range error and I'm stuck. The expected result (what I'm aiming at) would be a list with values:
[0, 2, 4, 6, 8]
Just to be more clear: I'm not after producing that particular list. The question is about how can I modify items of an empty list in a recursive way. As gnibbler showed below, initializing the list was the answer. Cheers.
Ruby (for example) lets you assign items beyond the end of the list. Python doesn't - you would have to initialise list1 like this
list1 = [0] * 5
So when doing this you are actually using i so you can just do your math to i and just set it to do that. there is no need to try and do the math to what is going to be in the list when you already have i. So just do list comprehension:
list1 = [2*i for i in range(5)]
Since you say that it is more complex, just don't use list comprehension, edit your for loop as such:
for i in range(5):
x = 2*i
list1[i] = x
This way you can keep doing things until you finally have the outcome you want, store it in a variable, and set it accordingly! You could also do list1.append(x), which I actually prefer because it will work with any list even if it's not in order like a list made with range
Edit: Since you want to be able to manipulate the array like you do, I would suggest using numpy! There is this great thing called vectorize so you can actually apply a function to a 1D array:
import numpy as np
list1 = range(5)
def my_func(x):
y = x * 2
vfunc = np.vectorize(my_func)
vfunc(list1)
>>> array([0, 2, 4, 6, 8])
I would advise only using this for more complex functions, because you can use numpy broadcasting for easy things like multiplying by two.
Your list is empty, so when you try to read an element of the list (right hand side of this line)
list1[i] = list1[i] + 2*i
it doesn't exist, so you get the error message.
You may also wish to consider using numpy. The multiplication operation is overloaded to be performed on each element of the array. Depending on the size of your list and the operations you plan to perform on it, using numpy very well may be the most efficient approach.
Example:
>>> import numpy
>>> 2 * numpy.arange(5)
array([0, 2, 4, 6, 8])
I would instead write
for i in range(5):
list1.append(2*i)
Yet another way to do this is to use the append method on your list. The reason you're getting an out of range error is because you're saying:
list1 = []
list1.__getitem__(0)
and then manipulate this item, BUT that item does not exist since your made an empty list.
Proof of concept:
list1 = []
list1[1]
IndexError: list index out of range
We can, however, append new stuff to this list like so:
list1 = []
for i in range(5):
list1.append(i * 2)

Categories

Resources