4

I have a while loop that goes over a two-dimensional list, to see if it can find a similar submission for it to be removed.

    i=0

while i <= len(my_list):
    if my_list[i] == userinput:
        del my_list[i]
        print("Entry Removed!")
    else:
        print("This publication does not exist")
    i+=1

What I wanted was for the code to print the message "This publication does not exist" if no matches were found. However, what happens right now is that everytime it compares an item, the code prints the sentence.

I understand why this happens but I have no idea how to fix it. What is the best way of addressing this issue?

EDIT: Changed list name from "list" to "my_list". My bad, I didn't actually call it that in the code, I just changed the name when uploading the question for ease of understanding.

Sanfer
  • 53
  • 6
  • 2
    You are deleting from a list while iterating over it. This is considered bad practice. – ltd9938 Jul 12 '18 at 20:28
  • 2
    ... basically because it will skip items and result in index errors. – Klaus D. Jul 12 '18 at 20:29
  • 2
    When you delete a list element the remaining elements shuffle down one. E.g. if you delete x[2] then what was x[3] becomes the new x[2] and what was x[4] becomes x[3], etc. Easier to create a new list one element at a time omitting those you don't need. By the way, don't use `list` as a variable name, it masks the system class `list`. – cdarke Jul 12 '18 at 20:30
  • I know you already accepted an answer for this but what would be an example of the user input? Is it a list? – Zev Jul 13 '18 at 13:25
  • @Zev yes,`userinput` is a list. – Sanfer Jul 13 '18 at 17:05

2 Answers2

3

You'll need to a boolean:

i = 0
found = False
while i <= len(list):
    if list[i] == userinput:
        del list[i]
        print("Entry Removed!")
        found = True
    i += 1

if not found:
    print("This publication does not exist")

Some unrelated suggestions:

  • It is better to not use the name list for a variable
  • Don't remove items from a list while iterating that same list. You can iterate the list in reverse:

    i = len(li) - 1
    found = False
    while i >= 0:
        if li[i] == userinput:
            del li[i]
            print("Entry Removed!")
            found = True
        i -= 1
    
    if not found:
        print("This publication does not exist")
    
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
0

Python's while loop has an else clause that executes if the loop completes without breaking out of it:

But let's go another way with this to avoid changing a list we are looping over:

list_ = [
    ["a", "b", "c"], 
    ["d", "f", "g"], 
    ["d", "f", "g"], 
    ["h", "i", "j"]
]

userinput = ["z", "z", "z"]
new_list = [x for x in list_ if x != userinput]

if list_ == new_list:
     print("This publication does not exist")

# This publication does not exist

Don't overwrite the list keyword. I changed it to list_ but you can change it to something more meaningful for your application.

Zev
  • 3,423
  • 1
  • 20
  • 41
  • 1
    This doesn't cover the 2D list though. – VoNWooDSoN Jul 12 '18 at 20:57
  • 1
    @VoNWooDSoN This actually works the same on 2d lists (I edited it to show that because that's closer to what the question is asking). The only thing I'm concerned about with it is time/space complexity. Also, it makes an assumption about the `userinput` but the accepted answer seems to make the same assumption that `userinput` is a list. – Zev Jul 13 '18 at 13:29
  • Oh, I see now... I assumed userinput was a single character, not an entire row. But your solution does match to what the OP had. – VoNWooDSoN Jul 13 '18 at 17:33