Python - Open multiple files in one For

Asked

Viewed 2,152 times

3

Could someone please help me explain why I can’t add the texts of each file to each position on 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?

Since I have 18 files, the most external is for me to pass and read all of them.

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

Code I display the 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 so it doesn’t get too big:

['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']
  • I can’t understand that question. What do you want to do? Your code does exactly what you’re told: opens all the files one after the other, and puts everyone’s text in a final list.

  • 1

    Who gave "upvote" in this question, could explain the same better?

  • I explained the question better.

  • @Nayronmorais I replicated your code and did not have the behavior you described. Each file was placed in a position on the list: https://repl.it/NbdC/0. Isn’t this the expected result? How are you displaying the list in the terminal?

  • In the same way as your replication! And yes, the result was this. I will edit the question by displaying an image with the terminal output.

  • This code is going around more than it should, but it’s "right". The error, if any, is at the point where you take the return value of the function and print it out. Or maybe with your files.

  • How do you turn around more than you should?

  • I added more information to the question!

  • @Andersoncarloswoss The only difference is that my version of Python is 3.5.

  • It is necessary that the order of the cards be kept in the final list?

  • You don’t have to... but I went after what @jsbueno said, I modified the line breaks of the files here and apparently it worked... I just thought it was strange that... someone could explain?

  • I have decided here!

  • @Nayronmorais what modifications he made?

  • I just took the line breaks from the files.

Show 9 more comments

1 answer

4


Solution with pathlib.Path

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

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

from pathlib import Path

path = Path('resources/letters/')

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

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

Thus, you can go through this eternal and use the method read_text to obtain the contents of each file:

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

Staying:

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 on Repl.it

However, in this way, there is no guarantee of the order of the result. That is, the content of carta_2.txt may come before carta_1.txt. If the order is required, you can sort the list by file name before reading the respective 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 on Repl.it

Yet, 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, it would be possible to 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 on Repl.it

  • 1

    Phyton is life ♥ !

  • @Magichat Phyton? hehe

  • 2

    Is it bro, num sabia? -> https://ideone.com/2QACcB

Browser other questions tagged

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