0
def my_list(enter_list): 
    #print(len(enter_list))--> 7 element
    for i in range(0, len(enter_list)): # THE PROBLEM IS HERE
        count = enter_list.count(enter_list[i])  
        if count >=2:
            enter_list.pop(i)
    return enter_list

print(my_list(["purple","coffee",2,6,2,"purple","steak"]))

At first there are 7 value in my list. But after I remove one of the same value from my list , my list's value is decreasing. İf I change the ranges range(0,len(enter_list)-2) like this. It works. I dont know how to change ranges automatically. ( I can change the ranges manually but it'll not work everytime. )

['coffee', 6, 2, 'purple', 'steak']

This is the output when I change the ranges manually.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    Don't use a `for` loop for this, since the range can't change once you create it. Use a `while` loop. – Barmar Dec 16 '21 at 16:00
  • you are looping in a list, which that you are poping elements from it. there could be better solution for it. change your logic – tanaydin Dec 16 '21 at 16:01
  • Okey I'm gonna try it. Thank you :) – Jack Harmon Dec 16 '21 at 16:02
  • No @MichaelSzczesny my question is about chaning ranges automatically. Barmar said u should use while loop. I'll try it. – Jack Harmon Dec 16 '21 at 16:05
  • create a second array which values are "< 2" and return it, that will be easier. – tanaydin Dec 16 '21 at 16:06
  • @GoldenLion For example there are 2 "purple" element in my list. I'm trying to delete 1 of them. Or if there are 3 "purple" element I'm trying to delete 2 of them. – Jack Harmon Dec 16 '21 at 16:09
  • so you want unique elements in your list? why don't you create an unique list using unique()? Do you need to preserve the index order in the list? – Golden Lion Dec 16 '21 at 16:10
  • Is this an exercise or are you looking to just `list(set(["purple","coffee",2,6,2,"purple","steak"]))` – JonSG Dec 16 '21 at 16:27

2 Answers2

1

Rather than attempt to modify the range you are iterating over, I would suggest you create a copy of the enter_list list and pop() the elements out of that list. That way you will be iterating over the full list of items, but you will return the modified version of the list without having to dynamically alter the range of your loop, which I don't believe is possible.

To quickly show the technique in your code:

def my_list(enter_list): 
    
    output_list = enter_list.copy()
    for i in range(0, len(enter_list)):
        count = enter_list.count(enter_list[i])  
        if count >=2:
            output_list.pop(i)

    return output_list

Here you return output_list, which will be your filtered version, but by copying the enter_list, you ensure you are iterating over the full set.

Just to add: using pop(i) here will likely result in you popping something out of range near the end of the loop, so this type of loop iterating over the elements might work best:

for items in enter_list:
    output_list.pop(item)

Then you ensure you are not going to pop() on an out of range index.

lepapillon
  • 55
  • 5
0

You could do like this:

def my_list(lst): 
    i = 0
    while True:
        cnt = lst.count(lst[i])  
        if cnt > 1:
            lst.pop(i)
        i += 1
        if len(lst) == i:
            break
    return lst

print(my_list(["purple","coffee",2,6,2,"purple","steak"]))

OUTPUT

['coffee', 6, 2, 'purple', 'steak']

The problem with your approach is that, in the for loop, the len of the list is only evaluated once - at the beginning. The reason why decreasing by 2 makes it work is because there are 2 elements which have one duplicate, so the loop does not go out of range.

nikeros
  • 3,302
  • 2
  • 10
  • 26