0

I know the answer is probably super simple, but I'm absolutely stuck on this short piece of code. The function has no effect on the input list when I run it.

def squareEven(array):
    for idx, val in enumerate(array):

        if idx % 2 == 0:
            val = val * val
        else:
            val = val

    return array

array = [1, 2, 4, 9, 20]

print(squareEven(array))
easyZero
  • 15
  • 2
  • You do nothing with calculated `val`. Why do you expect the list you pass as argument is affected? – buran Jan 23 '22 at 19:40
  • You don't ever change the list. When you say `val = val * val`, that creates a brand new integer object with no connection to the original list. – Tim Roberts Jan 23 '22 at 19:42
  • Does this answer your question about the behavior? https://softwareengineering.stackexchange.com/questions/341179/why-does-python-only-make-a-copy-of-the-individual-element-when-iterating-a-list – jh316 Jan 23 '22 at 19:43
  • Does this answer your question? [Can't modify list elements in a loop](https://stackoverflow.com/questions/19290762/cant-modify-list-elements-in-a-loop) – mkrieger1 Jan 23 '22 at 19:48

3 Answers3

2

You can also use the list comprehension to construct a new list with squared values when the index is even.


def squareEven(array):
    return [v**2 if i % 2 == 0 else v for (i, v) in enumerate(array)]

https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions

Lukasz Wiecek
  • 414
  • 2
  • 8
1

Here are two ways, one bad, one good:

def squareEven(array):
    for idx in range(len(array)):
        if idx % 2 == 0:
            array[idx] = array[idx] * array[idx]
    return array

array = [1, 2, 4, 9, 20]
print(squareEven(array))

This is better, because it doesn't damage the original array as a side effect:

def squareEven(array):
    new = []
    for idx,val in enumerate(array):
        if idx % 2 == 0:
            new.append(val * val)
        else:
            new.append(val)
    return new

array = [1, 2, 4, 9, 20]

print(squareEven(array))
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
0

The reason is that the enumerate function does not actually change the array itself but just returns the new one for you to use in the loop. The simple solution is to save the enumerate(array) into another variable and return it at the end of your function. Keep in mind, you will get an enumerated array at the end. You could map it to convert to a form you initially passed.

In the function, you wrote you don't save the actual result. The variable val you used is temporary and changing it doesn't affect the array you passed. It means that val has the value from the array but not reference to the element. To solve the issue, you can directly change the element by referencing it with idx.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65