Python Forum
My code is not working as I expected and I don't know why!
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
My code is not working as I expected and I don't know why!
#1
Exclamation 
My goal
My goal was to remove all elements from "inventario" that had a certain serial

The problem
The code cannot remove multiple elements from "inventario" even if they have the same serial

inventario = []
resposta = "S"
while resposta == "S":
    equipamento = [input("Nome:"), float(input("Valor:")), int(input("Número de Serie:")), input("Departamento:")]
    inventario.append(equipamento)
    resposta = input("Digite \"S\" para continuar: ").upper()

for elemento in inventario:
    print("\nNome.........:", elemento[0])
    print("Valor........:", elemento[1])
    print("Serial.......:", elemento[2])
    print("Departamento.:", elemento[3])

serial = int(input("Digite o serial do equipamento que será excluido:"))
for elemento in inventario:
    if elemento[2] == serial:
        inventario.remove(elemento)

for elemento in inventario:
    print("\nNome.........:", elemento[0])
    print("Valor........:", elemento[1])
    print("Serial.......:", elemento[2])
    print("Departamento.:", elemento[3])
Observations
I do not have any "errors" in the output
I am using Python 3.6
Reply
#2
Got to this link for loops that is on this forum and find the part with the header Changing sequence mid-loop
Reply
#3
If you knew why you probably would be asking the question.

This is bad
for elemento in inventario:
    if elemento[2] == serial:
        inventario.remove(elemento)
You should never modify the interable in a for loop. It doesn't work.

This program should remove all numbers >= 0. Since all the numbers are >= 0, the list should be empty at the end.
numbers = list(range(10))
for number in numbers:
    if number >= 0:
        numbers.remove(number)
print(numbers)
Output:
[1, 3, 5, 7, 9]
Why are any numbers left in the list?

It is easier to see why if you use while instead of for.
numbers = list(range(10))
index = 0
while index < len(numbers):
    number = numbers[index]
    print(index, number)
    if number >= 0:
        numbers.remove(number)
    index += 1
print(numbers)
Output:
0 0 1 2 2 4 3 6 4 8 [1, 3, 5, 7, 9]
1, 3, 5, 7 and 9 remain in the list, because these values are never tested. Removing numbers[0] modifies the list to be [1,2,3,4,5,6,7,8,9]. The next time through the loop we test numbers[1] which now holds 2. Removing numbers[1] modifies the list to be [1,3,4,5,6,7,8,9]. Next time though the loop we test numbers[2] which now holds 4. We repeat this until index >= len(numbers). We only test half the numbers, leaving the untested numbers in the list.

You can modify the iterable in a for loop if you start at the end and work backward. This way you don't skip any elements because removing an element does not shift untested elements in the list.
numbers = list(range(10))
for number in numbers[::-1]:  # Backward slice.  could also use reversed(numbers)
    if number >= 0:
        numbers.remove(number)
print(numbers)
Output:
[]
There is also some potential for problems using list.remove(). list.remove(value) removes the first list element that matches value. If I had duplicate numbers in my example, removing a number could result in skipping a number. This is not an issue with your program. Even though you may have multiple elements with the same serial, each elemento is unique.

But there is a better way to remove matching items from a list. Instead of removing items, build a new list that contains all the items you want to keep. Here I keep all numbers < 0.
numbers = list(range(10))
numbers = [number for number in numbers if number < 0]
print(numbers)
Output:
[]
To apply this to your problem.
inventario = [elemento for elemento in inventario if elemento[2] != serial]
If you don't understand how list comprehensions work, it is a compact way to write this for loop.
temp = []
for elemento in inventario:
    if elemento[1] != serial:
        temp.append(elemento)
inventario = temp
Reply
#4
Thank you for taking some of your time to answer and help me.

I just started learning Python, and you've been a big help.
I was following the instructions of a course when making this code, maybe it's better to switch courses since what they teach in the course is apparently wrong.

If anyone knows any courses or some other way to learn python the right way, feel free to let me know.
Reply
#5
Maybe that was the purpose of the exercise, to point out the dangers of modifying an iterable in a for loop.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Simple conditional not working as expected return2sender 8 1,013 Aug-27-2023, 10:39 PM
Last Post: return2sender
  New to Python - Not sure why this code isn't working - Any help appreciated TheGreatNinx 4 973 Jul-22-2023, 10:21 PM
Last Post: Pedroski55
  code not working when executed from flask app ThomasDC 1 902 Jul-18-2023, 07:16 AM
Last Post: ThomasDC
  Custom method to handle exceptions not working as expected gradlon93 3 1,038 Dec-22-2022, 07:12 PM
Last Post: deanhystad
  I am new to python and Could someone please explain how this below code is working? kartheekdas 2 1,019 Dec-19-2022, 05:24 PM
Last Post: kartheekdas
  My Code isn't working... End3r 4 1,942 Mar-21-2022, 10:12 AM
Last Post: End3r
  set and sorted, not working how expected! wtr 2 1,293 Jan-07-2022, 04:53 PM
Last Post: bowlofred
  I don't undestand why my code isn't working. RuyCab 2 1,998 Jun-17-2021, 03:06 PM
Last Post: RuyCab
  code is not working , can anybody help? RandomPerson69 4 2,919 Mar-22-2021, 04:24 PM
Last Post: deanhystad
  Short code for EventGhost not working Patricia 8 3,707 Feb-09-2021, 07:49 PM
Last Post: Patricia

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020