List containing only the last element in Python

Asked

Viewed 130 times

2

I’m going through a text file and putting its contents in a list of objects, in which each object contains two "string-like" attributes: word and meaning... The problem is that after I go through the.txt file with the for loop, the list only has the last element inserted. What could be going on ?

Code:

import itemLista
"""
Conteúdo do arquivo itemLista.py

class Item:
palavra = ''
significado = ''

"""

objIten = itemLista.Item()  # Cria um objeto do tipo Item

lista = []

i=0 # variável para controle de índice da lista

try:    
    arq = open('words.txt','r',encoding='utf-8') # abre o arquivo words.txt
    arq.seek(0) # Realinha o ponteiro no arquivo na posição 0
    for linha in arq:
        linha = linha.rstrip() # Retira o caractere '/n' da linha
        vet = linha.split(' ') # Quebra o conteúdo em duas partes (palavra e significado)
        objIten.palavra = vet[0]
        objIten.significado = vet[1]
        lista.append(objIten)
        print(lista[i].palavra,lista[i].significado) # Mostra todos os elementos da lista normal
        i = i + 1
    arq.close()
except Exception as e:
    print("Erro ao abrir o arquivo!\n",e)

for item in lista:
    print(item.palavra,item.significado) # Mostra apenas o ultimo elemento da lista várias vezes
  • You create objIten once and inside the loop you just change the values. Pro that does not create it also inside the loop?

1 answer

3


You need to create an individual instance of Item for each row processed within its loop for, follows an example commented:

# Objeto Item
class Item:
    def __init__(self):
        self.palavra = None
        self.significado = None

# Inicializa lista de items
lista = []

try:
    # Abre arquivo para leitura
    with open('words.txt', encoding='utf-8') as arq:

        # Para cada linha do arquivo...
        for linha in arq:
            # Remove caracteres de controle do final da linha
            linha = linha.rstrip()

            # Quebra linha em 2 partes (palavra e significado)
            vet = linha.split(' ')

            # Constroi uma instancia do objeto Item
            item = Item()

            # Preenche atributos de uma instancia do objeto Item
            item.palavra = vet[0]
            item.significado = vet[1]

            # Inclui item na lista
            lista.append(item)

    # Exibe Items da Lista
    for item in lista:
        print(f'{item.palavra} => {item.significado}')

except OSError as e:
    print("Erro ao abrir o arquivo: ", e)

Entree (words.txt):

cat gato
dog cachorro
duck pato
bird passáro
frog sapo
rabbit coelho
ant formiga
bee abelha
snake cobra
horse cavalo

Exit:

cat => gato
dog => cachorro
duck => pato
bird => passáro
frog => sapo
rabbit => coelho
ant => formiga
bee => abelha
snake => cobra
horse => cavalo

See working on Repl.it

In Python, everything can be even simpler:

class Item:
    def __init__(self, palavra, significado):
        self.palavra = palavra
        self.significado = significado

try:
    with open('words.txt', encoding='utf-8') as arq:
        lista = [Item(*linha.rstrip().split()) for linha in arq]

    for item in lista:
        print(f'{item.palavra} => {item.significado}')

except OSError as e:
    print("Erro ao abrir o arquivo: ", e)

See working on Repl.it

  • Perfect! It seems that I was entering in the list only the same instantiated object in memory and as much as I changed the value, it was a list of only one object... Kramba you did everything in a single line :) Thank you very much!

Browser other questions tagged

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