Python - Open multiple files in a For

3

Someone, please, could you help me explain why I can not add the texts of each file in each position of my list?

''' Funções para o processamento dos textos (cartas) para base de aprendizagem'''

PATH_LETTERS = 'resources/letters/'
MODE_OPEN = 'r'
NAME_DEFAULT_FILES = 'carta_{}'
EXENSION_LETTERS = '.txt'
PATH_FULL_LETTERS = PATH_LETTERS + NAME_DEFAULT_FILES + EXENSION_LETTERS


def get_text(size_letters=18):

    letters = []

    try:
        for i in range(1, (size_letters+1)):

            text = ''

            letter = open(PATH_FULL_LETTERS.format(i), MODE_OPEN)

            for line in letter.readlines():

                text += line

            letter.close()
            letters.append(text)
        return letters

    except FileNotFoundError:
        print('Error opening letter file')

Whenever I run this code the texts of all text files are in the same position in the list, why?

As I have 18 files, the most external is for me to go through and read all of them.

Basically, I have 18 text files and I want to read each one, and add the file contents in each position of the list, so .... in my view, the above code should work, however how much do I print in the terminal In the list, the contents of all files appear in a single position. So, could you help me?

Code that I display output:

import classifier as clr
import text_processor

if __name__ == '__main__':

    classifier = clr.Classifier()

    phrase = text_processor.get_text()

    print(phrase)

Terminal output with only 2 files to not get too large:

['São Paulo 18 de julho de 1988\nEdu estou deixando esta carta para mostrar a\nvocê o que sinto e o que estou sentindo.\nEdu são 2:15 hs da madrugada não consegui\ndormir um minuto se quer esta tudo doendo\ndentro de mim só em pensar que ti perdi de\nverdade.\nDu porque você fingiu, porque você mentiu\npara mim este tempo todo. Du não estou\naguentando mais, está sendo duro resistir\nesta dor tão grande que estou sentindo\ndentro de mim e por viver assim preferi\nmorrer.\nEdu quando lembrar-se de mim lembre-se que\nti amei e amei de verdade\n', 'Carlos\nEu precisava tanto falar contigo, pena, você\nnão deixou. Vou morrer te amando. Eu te\namo loucamente. Tudo o que fiz de errado, foi\numa necessidade de estar com você outra\nvez.\nVocê não quiz me ouvir. Agora será impossível\nme ouvir outra vez. Eu te amo. Se tomei esta\niniciativa foi simplesmente pelo fato de saber\nque nunca mais o teria de volta.\nPor mim, peça desculpas à minha mãe. Diga a\nela que eu a amo muito também porém não\nencontrei mais nenhuma existência para mim.\nEu te amo, tudo o que fiz foi porque o amava\ndemais. Tentei explicar isto à minha mãe: não\nse preocupe, será impossível te ligar outra\nvez.\n\nEu, Márcia, dou meus olhos, meus cabelos e\nmeu sangue a quem\nprecisar.\nJuro estar dizendo a verdade, perante todos e\na Deus.\n\nSem ele não viver mais.\n']
    
asked by anonymous 01.11.2017 / 21:45

1 answer

3

Solution with pathlib.Path

A simple way to do it is by using the pathlib , available from version 3.4 of Python, through class Path .

Passing as a constructor parameter a path, you will have an object representing the directory:

from pathlib import Path

path = Path('resources/letters/')

One of the methods of this class is glob , which can search for files that match a certain name:

letters_files = path.glob('carta_*.txt')

So you can go through this iterable and use the read_text method to get the contents of each file:

letters = [letter.read_text() for letter in letters_files]

Getting:

from pathlib import Path

path = Path('resources/letters/')
letters_files = path.glob('carta_*.txt')
letters = [letter.read_text() for letter in letters_files]

print(letters)

See working at Repl.it

However, in this way, there is no guarantee of the order of the result. That is, the contents of carta_2.txt may come before carta_1.txt . If ordering is required, you can sort the list by filename before reading its contents:

from pathlib import Path

path = Path('resources/letters/')
letters_files = path.glob('carta_*.txt')
letters = [letter.read_text() for letter in sorted(letters_files)]

print(letters)

See working in Repl.it

Still, this code can be written in just one line:

letters = [letter.read_text() for letter in Path('resources/letters/').glob('carta_*.txt')]

Producing the same result.

Solution following the logic of the question

By simplifying the code presented in the question, you could do something like:

PATH_LETTERS = 'resources/letters/'
MODE_OPEN = 'r'
NAME_DEFAULT_FILES = 'carta_{}'
EXENSION_LETTERS = '.txt'
PATH_FULL_LETTERS = PATH_LETTERS + NAME_DEFAULT_FILES + EXENSION_LETTERS


def get_text(size_letters=18):

    letters = []

    for i in range(size_letters):
        try:
            with open(PATH_FULL_LETTERS.format(i+1), MODE_OPEN) as letter:
                letters.append(letter.read())
        except OSError:
            print("Arquivo %s não encontrado" % PATH_FULL_LETTERS.format(i+1))

    return letters

print(get_text())

See working at Repl.it

    
02.11.2017 / 01:23