Is that a Python 3.6 bug?

Asked

Viewed 102 times

0

The code below is a demonstration of what I’m trying to do: I have a vector (todos) in which elements are added. The second vector (alguns) also receives new elements, and I need to know if the elements of alguns are already known to be in the vector todos. The already known elements, which are in the vector todos, are removed from the vector alguns:

todos = ["b", "g", "c", "e", "d", "a", "h", "d"]
print("todos:", todos)
alguns = ["h", "c", "k", "a", "d", "j", "a"]
print("alguns:", alguns)
for letra in todos:
    if letra in alguns:
    print("remover letra:", letra, ", pois esta em alguns:", alguns)
    alguns.remove(letra)
print ("alguns apos limpeza:", alguns)

The output of the execution, in the form the code is, is as follows:

todos: ['b', 'g', 'c', 'e', 'd', 'a', 'h', 'd']
alguns: ['h', 'c', 'k', 'a', 'd', 'j', 'a']
remover letra: c , pois esta em alguns: ['h', 'c', 'k', 'a', 'd', 'j', 'a']
remover letra: d , pois esta em alguns: ['h', 'k', 'a', 'd', 'j', 'a']
remover letra: a , pois esta em alguns: ['h', 'k', 'a', 'j', 'a']
remover letra: h , pois esta em alguns: ['h', 'k', 'j', 'a']
alguns apos limpeza: ['k', 'j', 'a']

Note that the last element of alguns has not been removed, perhaps because it is repeated, despite being in todos. If you modify the code to go through the vector alguns and check that the element is in todos, and then take it out, it doesn’t work either:

todos = ["b", "g", "c", "e", "d", "a", "h", "d"]
print("todos:", todos)
alguns = ["h", "c", "k", "a", "d", "j", "a"]
print("alguns:", alguns)
for letra in alguns:
    if letra in todos:
    print("remover letra:", letra, ", pois esta em alguns:", alguns)
    alguns.remove(letra)
print ("alguns apos limpeza:", alguns)

Exit:

todos: ['b', 'g', 'c', 'e', 'd', 'a', 'h', 'd']
alguns: ['h', 'c', 'k', 'a', 'd', 'j', 'a']
remover letra: h , pois esta em alguns: ['h', 'c', 'k', 'a', 'd', 'j', 'a']
remover letra: a , pois esta em alguns: ['c', 'k', 'a', 'd', 'j', 'a']
remover letra: a , pois esta em alguns: ['c', 'k', 'd', 'j', 'a']
alguns apos limpeza: ['c', 'k', 'd', 'j']

Any suggestions what I can do about it? I thought about sorting the vectors, but I think it’s not an option, by the type of element I’m using in the vectors of the original code.

I appreciate any help.

  • consider the possibility of using sets set(), will work better for what you want to do

  • I will search. Thank you!

1 answer

3


This is a Python 3.6 bug?

No, you would hardly find a bug in Python with such simple code.

The issue here is lack of knowledge about python’s native functions. Watch out for what it says to documentation of the function remove from a list:

list.remove(x)

Remove the first item from the list Whose value is x. It is an error if there is no such item.

Translating:

list.remove(x)

Removes the first element of the list whose value is x. It is an error if there is no such item

Notice that I was bored with first element as it is only the removed. See this simple example that touches on the problem:

alguns = ["h", "c", "k", "a", "d", "j", "a"]
alguns.remove("a")
print(alguns)  # ['h', 'c', 'k', 'd', 'j', 'a']  

Just removed the first a as expected, and for that there still remains a a on the list.

Check it out at Ideone

It does not have a function as direct as the remove to remove all occurrences, but has several ways to do so. Trying to keep the idea we have loops can for example use comprehensilist on:

todos = ["b", "g", "c", "e", "d", "a", "h", "d"]
alguns = ["h", "c", "k", "a", "d", "j", "a"]

for letra in todos:
    if letra in alguns:
        alguns = [x for x in alguns if x != letra]  # <-- aqui "remove" todas as ocorrencias

See also this example in Ideone

However it would be better to build a list only with the elements of alguns that do not exist at all:

nova = []
for letra in alguns:
    if letra not in todos and letra not in nova:
        nova.append(letra)
alguns = nova

In this solution add each letter to the new list if there is no todos nor in the nova list. Thus avoids having to create multiple lists several times, which is what is done in the first example.

Ideone

  • Yes, it’s really ignorance, I’m starting with Python now, and I haven’t read the documentation. In fact, I’m trying another solution: instead of using vectors, using objects and the function difference. I’ll probably have to change all the code for that. It would be something like this: todos = {"b", "g", "c", "e", "d", "a", "h", "d"} print("todos:", todos) alguns = {"h", "c", "k", "a", "d", "j", "a"} print("alguns:", alguns) alguns = alguns.difference(todos) print("alguns apos limpeza:", alguns) If unfeasible, I will use your solution. Thank you!

  • It was unviable, just for the little familiarity with the language. I used your solution. Vlws!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.