Python: Как отобразить верхние числа из текстовых файлов с помощью регулярных выражений - PullRequest
3 голосов
/ 10 апреля 2019

Мое задание - отображать виды сверху из двух разных текстовых файлов. Текстовые файлы отформатированы как «файл», затем следуют папки, представления, открываются / закрываются. У меня проблемы с отображением верхних представлений И заголовки path_folders должны быть в алфавитном порядке на тот случай, если представления были одинаковыми.

Я уже использовал glob для чтения двух разных файлов. Я даже использую регулярные выражения, чтобы убедиться, что файлы читаются так, как они должны. Я также знаю, что могу использовать сортировку / сортировку, чтобы сделать это в алфавитном порядке. Моя главная задача - в основном отображать вид сверху из текстовых файлов.

Вот мои файлы:

file1.txt

file Marvel/GuardiansOfGalaxy 300 1
file DC/Batman 504 1
file GameOfThrones 900 0
file DC/Superman 200 1
file Marvel/CaptainAmerica 342 0

file2.txt

file Science/Biology 200 1
file Math/Calculus 342 0
file Psychology 324 1
file Anthropology 234 0
file Science/Chemistry 444 1

** (Как можно судить по формату, третья вкладка представляет собой просмотров )

Вывод должен выглядеть следующим образом:

file GameOfThrones 900 0
file DC/Batman 504 1
file Science/Chemistry 444 1
file Marvel/CaptainAmerica 342 0
file Math/Calculus 342 0 
...

Кроме этого, здесь есть функция, над которой я сейчас работаю для отображения видов сверху:

records = dict(re.findall(r"files (.+) (\d+).+", files))
main_dict = {}

for file in records:
    print(file)
    #idk how to display the top views

return main_dict

Ответы [ 3 ]

0 голосов
/ 10 апреля 2019

Продолжая комментарий, который я сделал выше:

  1. Прочитать оба файла и сохранить их строки в списке

  2. Свести список

  3. Сортировка списка по представлениям в строке

Следовательно

list.txt:

file Marvel/GuardiansOfGalaxy 300 1
file DC/Batman 504 1
file GameOfThrones 900 0
file DC/Superman 200 1
file Marvel/CaptainAmerica 342 0

list2.txt:

file Science/Biology 200 1
file Math/Calculus 342 0
file Psychology 324 1
file Anthropology 234 0
file Science/Chemistry 444 1

И

fileOne = 'list.txt'
fileTwo = 'list2.txt'

result = []
with open (fileOne, 'r') as file1Obj, open(fileTwo, 'r') as file2Obj:
      result.append(file1Obj.readlines())
      result.append(file2Obj.readlines())

result = sum(result, [])                 # flattening the nested list
result = [i.split('\n', 1)[0] for i in result]  # removing the \n char

print(sorted(result, reverse=True, key = lambda x: int(x.split()[2]))) # sorting by the view

OUTPUT

[
 'file GameOfThrones 900 0', 'file DC/Batman 504 1', 'file Science/Chemistry 444 1', 
 'file Marvel/CaptainAmerica 342 0', 'file Math/Calculus 342 0', 
 'file Psychology 324 1', 'file Marvel/GuardiansOfGalaxy 300 1', 
 'file Anthropology 234 0', 'file DC/Superman 200 1', 'file Science/Biology 200 1'
]

Shorter-версия

with open (fileOne, 'r') as file1Obj, open(fileTwo, 'r') as file2Obj: result = file1Obj.readlines() + file2Obj.readlines()    
print(list(i.split('\n', 1)[0] for i in sorted(result, reverse=True, key = lambda x: int(x.split()[2]))))   # sorting by the view
0 голосов
/ 10 апреля 2019

Вы можете использовать следующий код:

#open the 2 files in read mode
with open('file1.txt', 'r') as f1, open('file2.txt', 'r') as f2:
  data = f1.read() + f2.read() #store the content of the two files in a string variable
  lines = data.split('\n') #split each line to generate a list
  #do the sorting in reverse mode, based on the 3rd word, in your case number of views
  print(sorted(lines[:-1], reverse=True, key=lambda x:int(x.split()[2])))

вывод:

['file GameOfThrones 900 0', 'file DC/Batman 504 1', 'file Science/Chemistry 444 1', 'file Marvel/CaptainAmerica 342 0', 'file Math/Calculus 342 0', 'file Psychology 324 1', 'file Marvel/GuardiansOfGalaxy 300 1', 'file Anthropology 234 0', 'file DC/Superman 200 1', 'file Science/Biology 200 1']
0 голосов
/ 10 апреля 2019

Извлечение критериев сортировки

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

>>> import re
>>> criteria_re = re.compile(r'file (?P<path>\S*) (?P<views>\d*) \d*')
>>> m = criteria_re.match('file GameOfThrones 900 0')
>>> res = (int(m.group('views')), m.group('path'))
>>> res
(900, 'GameOfThrones')

Сортировка

Теперь все это нужно просто применить к вашей коллекции файлов.Поскольку нам не нужен поиск по умолчанию, нам нужно установить параметр key функции поиска, чтобы он знал, что именно мы хотим отсортировать по:

def sort_files(files):
    lines = []
    for file in records:
        for line in open(file):
            m = criteria_re.match(line)
            # maybe do some error handling here, in case the regex doesn't match
            lines.append((line, (-int(m.group('views')), m.group('path'))))
            # taking the negative view count makes the comparison later a
            # bit more simple, since we can just sort be descending order
            # for both view as well as alphabetical path order 
    # the sorting criteria were only tagging along to help with the order, so
    # we can discard them in the result
    return [line for line, criterion in sorted(lines, key=lambda x: x[1])]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...