Working logic error with list

Asked

Viewed 87 times

-3

I’d like to know how I make the result equal to:

esta é a lista[{'h': 'h'}, {'h': 'j'}, {'h': 'z'}]
a, b= ['h', 'j', 'z'], list()
c= dict()

for i in a:
    print(i)
    c['h']= i
    print(c)
    b.append(c)
    
print(f'esta é a lista{b}')

3 answers

3

Consider this introductory reading:

Python is a highly object-oriented language. In fact, virtually all data items in a Python program are objects of a specific type or class.

Consider this code:
>>> print(300)
300

When presented with the print(300) statement, the interpreter does the following::

  • Creates an entire object
  • Gives value 300
  • Displays on console

A Python variable is a symbolic name that is a reference for an object. After an object is assigned to a variable, you can refer to the object by this name. But the data itself is still contained in the object.

For example:
>>> n = 300

This assignment creates an entire object with the value 300 and assigns the variable n for point to that object. Atribuição de Variável

Now consider the following statement:
>>> m = n

What happens when he runs?
Python does not create another object. It simply creates a new symbolic name or reference m which points to the same object for which n points out. Múltiplas referências para um único objeto

Then suppose you do this:
>>> m = 400

Python now creates a new whole object with the value 400 and m becomes a reference to it. Referências a objetos separados

Finally, suppose this instruction is executed below:

>>> n = "foo"

Python now creates a string object with the value "foo" and makes n reference to it. Objeto Órfão

No more reference to the whole object 300. He is orphaned and there’s no way to access it.

The life of an object begins when it is created, when at least one reference to it is created. During the lifetime of a object, additional references to it can be created, as seen above, and references to it may also be deleted. An object remains alive, so to speak, as long as there is at least one reference to it.

When the number of references to an object drops to zero, it is not more accessible. At this point, your lifespan is over. Python will end realizing that it is inaccessible and will recover the memory allocated to that can be used for something else. In computer jargon, this process is known as garbage collection.

Source: Translated and adapted from Real Python - Python variables

Aware of this, two problems with your code are identified right away:

  1. On the line c['h']= i each iteration on the elements of a the value whose key object h, contained in the object referenced by c, reference is superscripted by the reference contained in i. For one dictionary Python does not have duplicate keys at each new value written in a key replaces the previous one.
  2. On the line b.append(c) each iteration on the elements of a the same reference to the object referenced by c is repeatedly appended to the list referenced by b.

Behold:

a, b= ['h', 'j', 'z'], list()
c= dict()

for i in a:
    print(i)
    #A cada iteração é sobrescrito o valor da chave h ao objeto referenciado por c.
    c['h']= i   
    print(c)
    #A cada iteração a mesma referencia a c é adicionado a lista em b.
    b.append(c)  
    
print(f'esta é a lista{b}')

Resulting in:

h
{'h': 'h'}
j
{'h': 'j'}
z
{'h': 'z'}
esta é a lista[{'h': 'z'}, {'h': 'z'}, {'h': 'z'}]

The immediate repair for your code to work as you want is to cause unwanted data overwriting on c['h']= i and the repeated addition of the same reference in b.append(c) give rise to the literal creation of a structure of the {'h': i} and the fitting of that structure into b.

a, b= ['h', 'j', 'z'], list()
#c= dict()                     #Não é mais necessário. 

for i in a:
    print(i)
    c = {'h': i}               #A cada iteração cria um dicionário literal e o referencia em c.
    print(c)
    b.append(c)                #Apensa em b a referência em c.
    
print(f'esta é a lista{b}')

Resulting:

h
{'h': 'h'}
j
{'h': 'j'}
z
{'h': 'z'}
esta é a lista[{'h': 'h'}, {'h': 'j'}, {'h': 'z'}]

Simplified the code:

a, b= ['h', 'j', 'z'], list()
for i in a:
    b.append({'h': i})               
        
print(f'esta é a lista{b}')
#esta é a lista[{'h': 'h'}, {'h': 'j'}, {'h': 'z'}]

Still using list comprehensions:

l = [{'h': i} for i in ['h', 'j', 'z']] 
print(f'esta é a lista{l}')
#esta é a lista[{'h': 'h'}, {'h': 'j'}, {'h': 'z'}]
  • Help well didactic, I assume I came to see the answer first but I will soon return to read why the "error" occurred. Today I was also with very weak logic, I knew the error but I did not think how to fix it. Thanks for the help!

0

What you’re doing in the loop is adding a reference to the C dictionary at the end of the list. Every time you change C, it will change, these changes will be reflected in the list.

To do what you want you would need to create a new dictionary when putting it on the list:

for i in a:
    c['h']= i
    # A linha abaixo cria uma cópia do dicionário 
    # e coloca no final da lista
    b.append(dict(c))
  • Thanks for the help.

0

You don’t need to use FOR for this, just create a list inline that will generate a dictionary.

a = ['h', 'j', 'z']
c = [{a[0] : i} for i in a]

print(f'esta é a lista{c}')

Output:

esta é a lista[{'h': 'h'}, {'h': 'j'}, {'h': 'z'}]

This mode can be considered a little more pythonic.

  • In reality I need the FOR is that this part of the code is a fragment of another that has almost the same function, but instead of a list it goes through a WEB page. But thanks for the help.

  • In that case I suggest adding this information about the need to use FOR to your question.

  • I know there is a need, but today I asked this question only because I am too tired. In normal situations I could already solve it. And if I did not use the FOR I would implement, this quiet. Thanks again for the help and the observation;

Browser other questions tagged

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