Manipulating List Elements Inside a For Loop in Python


Suppose you have a list nums and your task is to increment every number in that list by one.

The first idea that might come to your mind is to write a for loop like this:

nums = [1, 2, 3]

for num in nums:
  num += 1
  
print(nums)

but when you run this code, you'll be surprised to see that the output is:

[1, 2, 3]

No element in nums changed its value. How is this possible since we clearly do num += 1 for every num in nums?


Let's talk about copies:

Take a look at this code:

number = 100

number_copy = number

number_copy += 1

print(number_copy) # Output: 101
print(number) # Output: 100

Although we wrote number_copy = number, this doesn't mean that number and number_copy are one and the same.

number_copy is a completely different entitity (stored at a different memory address) than number.

What we did is initialize this new number_copy entity with the value of number. That's why we say the number_copy is a copy of number.

And so number_copy += 1 will only increment number_copy and won't have any effect on number.


The loop variable is just a copy:

This is what also happens with a for loop.

Whenever you write a for loop, the loop variable (in our case num) is just a copy of the current item of the list, not the item itself.

This code

nums = [1, 2, 3]

for num in nums:
  num += 1

works exactly like this code:

nums = [1, 2, 3]

num = nums[0]
num += 1

num = nums[1]
num += 1

num = nums[2]
num += 1

Notice that only the variable num is being manipulated, which has nothing to do with the actual entries of the list nums.

You'll see this better if we also print the value of num on each iteration.

nums = [1, 2, 3]

for num in nums:
  num += 1
  print(num)

print(nums)

The output of this code is:

2
3
4
[1, 2, 3]

Looping over the indices:

In order to manipulate the entries of some list we have to loop over the items' indices:

nums = [1, 2, 3]

for index in range(len(nums)):
  nums[index] += 1
  
print(nums) # Output: [2, 3, 4]

This code works exactly like this one:

nums = [1, 2, 3]

index = 0
nums[index] += 1

index = 1
nums[index] += 1

index = 2
nums[index] += 1

print(nums)

In this way we directly manipulate the actual entries of the list (nums[0], nums[1], etc.)

Assignment:

Fix our code such that it correctly increments (adds one to) the even numbers of nums and decrements (subtracts one from) the odd ones.

Solution

To solve this problem, we need to loop over the indices of the list and check if each number is even or odd. If the number is even, we increment it by one. If the number is odd, we decrement it by one. Here is the detailed solution:

nums = [1, 2, 3, 4, 5]

# Loop over the indices of the list
for index in range(len(nums)):
    # Check if the number is even
    if nums[index] % 2 == 0:
        nums[index] += 1  # Increment even numbers by 1
    else:
        nums[index] -= 1  # Decrement odd numbers by 1

print(nums)  # Output: [0, 3, 2, 5, 4]

Explanation

Let's break down the solution step-by-step:

  1. We start with a list of numbers: nums = [1, 2, 3, 4, 5].
  2. We use a for loop to iterate over the indices of the list. The range(len(nums)) function generates a sequence of indices from 0 to the length of the list minus one.
  3. Inside the loop, we check if the current number is even using the modulus operator %. If nums[index] % 2 == 0 is true, the number is even.
  4. If the number is even, we increment it by one using nums[index] += 1.
  5. If the number is odd, we decrement it by one using nums[index] -= 1.
  6. Finally, we print the modified list.

Common Pitfalls and Best Practices

Here are some common mistakes to avoid and best practices to follow:

  • Modifying the loop variable: Remember that the loop variable is just a copy of the list element. Modifying it won't change the original list. Always use indices to modify list elements.
  • Using meaningful variable names: Use descriptive variable names to make your code more readable and maintainable.
  • Testing edge cases: Test your code with different inputs, including edge cases like an empty list or a list with all even or all odd numbers.

Advanced Techniques

For more advanced manipulation of list elements, you can use list comprehensions or the map function. Here is an example using a list comprehension:

nums = [1, 2, 3, 4, 5]

# Using list comprehension to increment even numbers and decrement odd numbers
nums = [num + 1 if num % 2 == 0 else num - 1 for num in nums]

print(nums)  # Output: [0, 3, 2, 5, 4]

Debugging and Testing

When debugging and testing your code, consider the following tips:

  • Print statements: Use print statements to check the values of variables at different points in your code.
  • Unit tests: Write unit tests to verify the correctness of your code. Use a testing framework like unittest or pytest.
  • Edge cases: Test your code with edge cases to ensure it handles all possible inputs correctly.

Thinking and Problem-Solving Tips

Here are some strategies for approaching problems related to list manipulation:

  • Break down the problem: Divide the problem into smaller, manageable parts and solve each part step-by-step.
  • Use pseudocode: Write pseudocode to outline your approach before implementing it in code.
  • Practice: Solve similar problems and practice coding exercises to improve your problem-solving skills.

Conclusion

In this lesson, we learned how to manipulate list elements inside a for loop in Python. We discussed the importance of understanding that the loop variable is just a copy of the list element and how to correctly modify list elements using indices. We also covered common pitfalls, best practices, advanced techniques, and debugging tips. By mastering these concepts, you can write more efficient and maintainable code.

Additional Resources

For further reading and practice problems, check out the following resources: