0

I am making a Gui app in python where i was using a simple snippet. i cannot understand why this happened. The Code:

k = ["Saikat","Ananya"]
names = ["Saikat","Ananya","Sam"]

for i in range (0,len(k)):
    if k[i] in names:
        names.pop(i)
    
print(names)

Here Finally the name array consited of "Ananya" instead of what it should have "Sam". I couldn't figure out what is going wrong here.

Thank you all your answer guys, but here is the real problem i am facing. I tried to minimize the code, but the problem i am facing in relaity dosen't got solved by these solutions.

app_list = [["saikat","male"],["ananya","female"],["sam","male"],["joe","male"]]
k= ["Sam","joe"]
for i in (app_list):
        print(i[0])
        if i[0] in k:
            app_list.remove(i)

now it does delete "sam" but it dosen't delete "joe".

Abdodt
  • 138
  • 7
  • First, you can see that `'Sam' == 'sam'` is `False`. Second print `app_list` while looping (see my answer) and you can figure out that the list gets modified while looping. The quickest fix is looping through a copy of the list: `for i in app_list.copy():` – iGian Dec 21 '20 at 07:33

6 Answers6

4

When you pop Saikat from names, it becomes ["Ananya","Sam"], so when your i becomes 1, it pops names[1] from names, which is Sam and left you with ["Ananya"]

A fix would be,

for name in k:
    if name in names:
        names.remove(name)
kennysliding
  • 2,783
  • 1
  • 10
  • 31
1

List's pop functions remove an item by a given index in that list. you wish to remove a specific value from a list, therefore you need to do:

names.remove(k[i])

What you currently do is, as mentioned before, removing a value from names list by a given index. so you iterate over k, finds the name Saikat at index 0 and them pop out the item in index 0 in names array, then you find Ananya at index 1 on k but now, after the removal of the previous name from names, it's index is now on 0 in names which causes an invalid removal. therefore you should either reverse-iterate those lists or just remove by value as suggested.

Or Y
  • 2,088
  • 3
  • 16
1

Instead of

names.pop(i)

Use

names.pop(names.index(k[i]))
Sagun Devkota
  • 495
  • 3
  • 10
1

This is a tricky thing to do in multi-dimensional array. When trying to remove elements from a list when it is reiterating will mess up the indices. You can read this To understand how. It gets trickier when dealing with 2-dimensional arrays. However, I managed to solve this with two steps. First from you're main problem

app_list = [["saikat","male"],["ananya","female"],["sam","male"], 
["joe","male"]]
k= ["Sam","joe"]
for i in (app_list):
        print(i[0])
        if i[0] in k:
            app_list.remove(i)

you are looping a 2-dimensional array and checking it with a single-Dimensional array, again, this will cause problems with the indices. What you need to do is take out the main elements from the list with which you going to compare. In this case the names(like Saikat,Ananya etc...) in app-list, and turn them into a separate list.

x = []
for i in app_list:
    print(i[0])
    x.append(i[0])
    print(x)

Once you have X List with the main elements for comparison with the counter-part K which you are using to compare with you need to see IF NOT the elements are in K. And it's best to use List comprehension here to keep it concise.

print([Elements for Elements in x if Elements not in k ])

Elements here is the variable where the list of values that are Not in K is stored and displayed. Else I don't think you can remove a list from 2d-array by another List unless you do it individually.

Abdodt
  • 138
  • 7
0

If your aim is only to remove k list elements from the names list, an alternative solution is to use set: the difference between two sets corresponds to removing the intersecting elements.

result = set(k) - set(names)
print(result)

>>> Sam

NB A property of set structure is that it has no duplicates. For example:

mylist = ["ada","luke","ada"]
print(set(mylist))
>>> ada luke
  • Set operations are fast compared to other list loop methods (more about this here)
  • Read the docs
Wippo
  • 853
  • 8
  • 22
0

I'd suggest you debug your code printing out each step, this helps a lot learning by yourself, for example:

k = ["Saikat","Ananya"]
names = ["Saikat","Ananya","Sam"]

for i in range (0,len(k)):
    print('names: ', names)
    print('i:', i)
    if k[i] in names:
        print('k[i]: ', k[i])
        print('names.pop(i): ', names.pop(i))
    print('-'*30)
print('names: ', names)
print('-'*50)

Which results in:

# names:  ['Saikat', 'Ananya', 'Sam']
# i: 0
# k[i]:  Saikat
# names.pop(i):  Saikat
# ------------------------------
# names:  ['Ananya', 'Sam']
# i: 1
# k[i]:  Ananya
# names.pop(i):  Sam
# ------------------------------
# names:  ['Ananya']
# --------------------------------------------------

As you can see, the list kinda "rotates/shifts" and you are shooting at the wrong element.


One fix is for example How to remove the first Item from a list?, so use names.pop(0) instead:

k = ["Saikat","Ananya"]
names = ["Saikat","Ananya","Sam"]

for i in range (0,len(k)):
    print('names: ', names)
    print('i:', i)
    if k[i] in names:
        print('k[i]: ', k[i])
        print('names.pop(0): ', names.pop(0))
    print('-'*30)
print('names: ', names)
print('-'*50)

Where the result is:

# names:  ['Saikat', 'Ananya', 'Sam']
# i: 0
# k[i]:  Saikat
# names.pop(0):  Saikat
# ------------------------------
# names:  ['Ananya', 'Sam']
# i: 1
# k[i]:  Ananya
# names.pop(0):  Ananya
# ------------------------------
# names:  ['Sam']
# --------------------------------------------------

Important Note

It works just because this is a very special case where k == names[:-1]. Good for learning. For a most general case you need to take a different approach, as many answered in this thread.

iGian
  • 11,023
  • 3
  • 21
  • 36