Is this a Python 3.6 bug?

0

The following code 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 we need to know if elements of alguns are already known, because they are in the todos vector. The already known elements, which are in the todos vector, are removed from the 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 that 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 was not removed, perhaps because it was repeated, even though it is in todos . If you modify the code to loop through the alguns vector and check that the element is in todos , and then remove it, it also does not work:

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)

Output:

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 on what I can do to resolve? I thought about ordering the vectors, but I do not think it's an option, because of the type of element I'm using in the vectors of the original code.

Thanks for any help.

    
asked by anonymous 15.11.2018 / 13:52

1 answer

3
  

Is this a Python 3.6 bug?

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

The issue here is lack of knowledge about native python functions. Notice what documentation about the remove function of a list says:

  

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)

     

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

Notice that I emphasized the first element because it's just removed. Here's a 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']  

Only removed the first a as expected, so there is still a a left in the list.

See it on Ideone

It does not have as direct a function as remove to remove all occurrences, but there are several ways of doing so. Trying to keep your idea in loops might for example use list comprehension :

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 this example on Ideone

However, it would be better to build a list only with alguns elements 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 workaround add each letter to the new list if it does not exist in todos nor nova list. This avoids having to create multiple lists multiple times, which is what is done in the first example.

Ideone

    
15.11.2018 / 15:00