Цепочка имен файлов в python

Я НЕ МОГУ ИСПОЛЬЗОВАТЬ НИКАКИЕ ИМПОРТНЫЕ БИБЛИОТЕКИ. У меня есть эта задача, где у меня есть несколько каталогов, содержащих несколько файлов; каждый файл содержит, помимо некоторых слов, имя следующего открываемого файла в первой строке. Как только каждое слово каждого файла, содержащегося в каталоге, открыто, они должны быть обработаны таким образом, чтобы возвращалась одна строка; такая строка содержит в своей первой позиции наиболее часто встречающуюся первую букву каждого слова, встречавшегося ранее, во второй позиции — наиболее часто встречающуюся вторую букву и так далее. Мне удалось сделать это с каталогом, содержащим 3 файла, но он не использует какой-либо цепной механизм, а передает локальные переменные. Некоторые из моих коллег по колледжу предложили мне использовать нарезку списков, но я не могу понять, как это сделать. Я НЕ МОГУ ИСПОЛЬЗОВАТЬ НИКАКИЕ ИМПОРТНЫЕ БИБЛИОТЕКИ. Вот что я получил:

'''
    The objective of the homework assignment is to design and implement a function
    that reads some strings contained in a series of files and generates a new
    string from all the strings read.
    The strings to be read are contained in several files, linked together to
    form a closed chain. The first string in each file is the name of another
    file that belongs to the chain: starting from any file and following the
    chain, you always return to the starting file.
    
    Example: the first line of file "A.txt" is "B.txt," the first line of file
    "B.txt" is "C.txt," and the first line of "C.txt" is "A.txt," forming the 
    chain "A.txt"-"B.txt"-"C.txt".
    
    In addition to the string with the name of the next file, each file also
    contains other strings separated by spaces, tabs, or carriage return 
    characters. The function must read all the strings in the files in the chain
    and construct the string obtained by concatenating the characters with the
    highest frequency in each position. That is, in the string to be constructed,
    at position p, there will be the character with the highest frequency at 
    position p of each string read from the files. In the case where there are
    multiple characters with the same frequency, consider the alphabetical order.
    The generated string has a length equal to the maximum length of the strings
    read from the files.
    
    Therefore, you must write a function that takes as input a string "filename"
    representing the name of a file and returns a string.
    The function must construct the string according to the directions outlined
    above and return the constructed string.
    
    Example: if the contents of the three files A.txt, B.txt, and C.txt in the
    directory test01 are as follows
    
    
    test01/A.txt          test01/B.txt         test01/C.txt                                                                 
    -------------------------------------------------------------------------------
    test01/B.txt          test01/C.txt         test01/A.txt
    house                 home                 kite                                                                       
    garden                park                 hello                                                                       
    kitchen               affair               portrait                                                                     
    balloon                                    angel                                                                                                                                               
                                               surfing                                                               
    
    the function most_frequent_chars ("test01/A.txt") will return "hareennt".
    '''

        def file_names_list(filename):
            intermezzo = []
            lista_file = []
        
            a_file = open(filename)
        
            lines = a_file.readlines()
            for line in lines:
                intermezzo.extend(line.split())
            del intermezzo[1:]
            lista_file.append(intermezzo[0])
            intermezzo.pop(0)
            return lista_file
        
        
        def words_list(filename):
            lista_file = []
            a_file = open(filename)
        
            lines = a_file.readlines()[1:]
            for line in lines:
                lista_file.extend(line.split())
            return lista_file
        
        def stuff_list(filename):
            file_list = file_names_list(filename)
            the_rest = words_list(filename)
            second_file_name = file_names_list(file_list[0])
            
            
            the_lists = words_list(file_list[0]) and 
            words_list(second_file_name[0])
            the_rest += the_lists[0:]
            return the_rest
            
        
        def most_frequent_chars(filename):
            huge_words_list = stuff_list(filename)
            maxOccurs = ""
            list_of_chars = []
            for i in range(len(max(huge_words_list, key=len))):
                for item in huge_words_list:
                    try:
                        list_of_chars.append(item[i])
                    except IndexError:
                        pass
                    
                maxOccurs += max(sorted(set(list_of_chars)), key = list_of_chars.count)
                list_of_chars.clear()
            return maxOccurs
        print(most_frequent_chars("test01/A.txt"))

Пожалуйста, предоставьте полный пример с входными данными и ожидаемым результатом. stackoverflow.com/help/минимально-воспроизводимый-пример

C-3PO 19.11.2022 15:52

Готово, теперь должно быть понятнее.

youngsoyuz 19.11.2022 16:02

Слишком много произвольных прыжков вокруг кролика. Если вы перестали все разделять и вместо этого сделали одну четкую функцию, которая выполняет всю работу, ваша проблема, скорее всего, исчезнет. Посмотрите на свою функцию имен файлов, вам нравится 50 вещей, чтобы получить самое первое в файле...

OneMadGypsy 19.11.2022 16:03

Однако сегментация кода часто является хорошей идеей; лично я бы сначала реализовал most_frequent_letter(list_of_words, index) и протестировал его, а затем работал над остальной частью задания.

Swifty 19.11.2022 16:08

@Swifty ~ Не каждый может жонглировать 3 или более мячами, но любой, у кого есть руки и руки, определенно может жонглировать одним. Сегментация имеет смысл только в том случае, если у вас есть похожие, но не идентичные операции, которые имеют общую часть. Если вы просто пытаетесь сделать что-то одно, нет смысла разбивать его на более мелкие части.

OneMadGypsy 19.11.2022 16:12

Мне удалось выполнить функцию most_frequent_letter. Проблема в том, как открыть файлы именно так, как хочет моя домашняя работа. Это основная проблема, которая у меня есть. Я делаю 50 вещей, чтобы добраться до первой строки файла, потому что это то, что нужно сделать, и не знаю, как (первая строка файла содержит имя следующего, который нужно открыть)

youngsoyuz 19.11.2022 16:13

Я сегментировал вещи, потому что это сначала имело смысл для меня, но это не главная проблема, опять же.

youngsoyuz 19.11.2022 16:14

«Я делаю 50 вещей, чтобы добраться до первой строки файла, потому что это то, что нужно сделать» — это совсем не так. Вы можете сделать то же самое в двух строках кода, и тогда вы поймете, что нет никаких причин для того, чтобы это была функция. Если вы продолжите следовать этой линии, вы в конечном итоге соберете все в одной функции, и это, вероятно, сработает, потому что у вас нет кода, который на 80% состоит из шума.

OneMadGypsy 19.11.2022 16:16

Мой парень, ты все еще игнорируешь мою проблему, пожалуйста, помоги мне решить ее, если можешь, иначе до свидания.

youngsoyuz 19.11.2022 16:19

Я просто показал очень плохую попытку решить проблему. Я задал вопрос, потому что ищу лучшее решение.

youngsoyuz 19.11.2022 16:20

Хорошо ~ "до свидания" звучит хорошо. Ты еще слишком новичок, чтобы понять, что я оказал тебе лучшую помощь из всех. Моя помощь заставляет вас помогать себе, реализовывать и становиться более независимым программистом. Ты просто хочешь, чтобы тебе передали ответы, и из-за того, как ты только что говорил со мной, я не собираюсь тебе их давать, чемпион.

OneMadGypsy 19.11.2022 16:22

Насколько я понимаю, тестовые батареи предоставят имя файла в качестве входных данных и позволят вам работать с ним; поэтому ваш код должен начинаться с «filename = input()»; затем напишите код, который открывает этот файл, получает от него то, что вам нужно (следующее имя файла и список слов) и переходите к следующему файлу (сохраняйте набор уже проанализированных имен файлов, чтобы вы знали, когда зациклились, и используйте цикл while); когда все файлы будут готовы, переходим к разбору слов. И, конечно же, используйте 3 файла, представленные в качестве примера, для проверки вашего кода.

Swifty 19.11.2022 17:38
Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
2
12
92
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это назначение относительно легко, если код имеет хорошую структуру. Вот полная реализация:

def read_file(fname):
    with open(fname, 'r') as f:
        return list(filter(None, [y.rstrip(' \n').lstrip(' ') for x in f for y in x.split()]))

def read_chain(fname):
    seen   = set()
    new    =  fname
    result = []
    while not new in seen:
        A          = read_file(new)
        seen.add(new)
        new, words = A[0], A[1:]
        result.extend(words)
    return result

def most_frequent_chars (fname):
    all_words = read_chain(fname)
    result    = []
    for i in range(max(map(len,all_words))):
        chars = [word[i] for word in all_words if i<len(word)]
        result.append(max(sorted(set(chars)), key = chars.count))
    return ''.join(result)

print(most_frequent_chars("test01/A.txt"))
# output: "hareennt"

В приведенном выше коде мы определяем 3 функции:

  1. Read_file: простая функция для чтения содержимого файла и возврата списка строк. Команда x.split() позаботится о любых пробелах или табуляциях, используемых для разделения слов. Последняя команда list(filter(None, arr)) гарантирует, что пустые строки будут удалены из решения.

  2. Read_chain: Простая процедура для перебора цепочки файлов и возврата всех содержащихся в них слов.

  3. Most_frequent_chars: Простая рутина, в которой тщательно подсчитываются наиболее часто встречающиеся символы.


PS. Эта строка кода у вас была очень интересной:

MaxOccurs += max(sorted(set(list_of_chars)), key = list_of_chars.count)

Я отредактировал свой код, чтобы включить его.


Оптимизация сложности пространства

Объемную сложность предыдущего кода можно улучшить на порядки, если сканировать файлы без сохранения всех слов:

def scan_file(fname, database):
    with open(fname, 'r') as f:
        next_file = None
        for x in f:
            for y in x.split():
                if next_file is None:
                    next_file = y
                else:
                    for i,c in enumerate(y):
                        while len(database) <= i:
                            database.append({})
                        if c in database[i]:
                            database[i][c] += 1
                        else:
                            database[i][c]  = 1
        return next_file

def most_frequent_chars (fname):
    database  =  []
    seen      =  set()
    new       =  fname
    while not new in seen:
        seen.add(new)
        new  =  scan_file(new, database)
    return ''.join(max(sorted(d.keys()),key=d.get) for d in database)
print(most_frequent_chars("test01/A.txt"))
# output: "hareennt"

Теперь сканируем файлы, отслеживающие частоту появления символов в database, не сохраняя промежуточные массивы.

Я заметил, что его можно немного улучшить, написав кодировку = "utf-8" внутри первой открытой функции, чтобы она могла читать символы любого типа. Еще раз спасибо

youngsoyuz 19.11.2022 19:27

Здорово, я рад, что смог помочь. Извините за задержку с ответом, ура,

C-3PO 19.11.2022 19:28

Я добавил новую версию, оптимизировав пространственную сложность кода.

C-3PO 20.11.2022 11:46

Хорошо, вот мое решение:

def parsi_file(filename):
    
    visited_files = set()
    words_list = []
    
    # Getting words from all files
    while filename not in visited_files:
        visited_files.add(filename)
        with open(filename) as f:
            filename = f.readline().strip()
            words_list += [line.strip() for line in f.readlines()] 
    
    # Creating dictionaries of letters:count for each index
    letters_dicts = []
    for word in words_list:
        for i in range(len(word)):    
            if i > len(letters_dicts)-1:
                letters_dicts.append({})
            letter = word[i]
            if letters_dicts[i].get(letter):
                letters_dicts[i][letter] += 1
            else:
                letters_dicts[i][letter] = 1
        
     # Sorting dicts and getting the "best" letter
    code = ""
    for dic in  letters_dicts:
        sorted_letters = sorted(dic, key = lambda letter: (-dic[letter],letter))
        code += sorted_letters[0]
        
    return code
  • Сначала мы получаем word_list из всех файлов.
  • Затем для каждого индекса мы создаем словарь букв во всех словах по этому индексу с их количеством.
  • Теперь мы сортируем ключи словаря по убыванию количества (-count), а затем по алфавиту.
  • Наконец, мы получаем первую букву (то есть ту, у которой максимальное количество) и добавляем ее к «кодовому» слову для этой тестовой батареи.

Обновлено: с точки зрения эффективности синтаксический анализ всех слов для каждого индекса будет ухудшаться по мере роста количества слов, поэтому было бы лучше настроить код, чтобы одновременно создавать словари для каждого индекса и анализировать список слов только один раз. . Сделанный.

Мне очень жаль, но я не указал, что не могу использовать функцию ввода, как вы сделали в начале своего кода. Я все еще очень благодарна вам за вашу помощь.

youngsoyuz 19.11.2022 19:08

Действительно, я сосредоточился на «вводе» и забыл о «функции». Ну, я просто изменю 1-ю строку :) Готово; и поскольку они не форсировали имя функции, я решил перейти на полный вагнеровский подход;)

Swifty 19.11.2022 19:45

Другие вопросы по теме