Моя задача - отобразить виды сверху из двух разных текстовых файлов. Текстовые файлы форматируются как «файл», за которым следует путь к папке, представления, открытие/закрытие. У меня возникли проблемы с отображением верхних видов И заголовков path_folders должны быть в алфавитном порядке на тот случай, если представления были одинаковыми.
Я уже использовал glob для чтения двух разных файлов. Я даже использую регулярное выражение, чтобы убедиться, что файлы читаются так, как это должно быть. Я также знаю, что могу использовать sort/sorted, чтобы сделать это в алфавитном порядке. Моя главная забота в основном заключается в отображении верхних видов из текстовых файлов.
Вот мои файлы:
файл1.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
файл2.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
@NPE Я знаю, что могу использовать это в конце, но я думаю, что моя главная задача — отображать основные виды на основе строк, заданных в моих текстовых файлах.
Regex не предоставляет никаких функций для получения самого короткого или самого длинного или максимального или минимального значения. Он используется для извлечения текста. Извлеките эти числа, которые вам нужно отсортировать, и отсортируйте.
Как насчет чтения обоих файлов, сохранения результатов в списке и сортировки по значениям?
@wiktor как мне их извлечь? Я никогда не делал этого раньше. Я чувствую, что с тех пор, как я превратил свое регулярное выражение в раздел, я мог бы сделать заголовок ключом, а просмотры - значением. Это способ рассматривать это как? Но я не очень уверен, как это реализовать.
@dirtybit, как я могу отсортировать значения, если я должен превратить регулярное выражение в словарь?
Дай мне минутку!
Судя по вашим данным, вы можете извлечь каждое число с помощью line.split()[2]
, регулярное выражение не требуется.
@smokingpenguin, посмотрите, поможет ли ответ, который я разместил?
Во-первых, вам нужно получить информацию, по которой вы хотите отсортировать каждую строку. Вы можете использовать это регулярное выражение для извлечения представлений и пути из ваших строк:
>>> 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])]
откуда взялась буква m в m.group? Я пытаюсь следовать вашему коду, но я не могу следовать первой части извлечения. Есть ли способ показать мне, как это выводится в rep.l или что-то в этом роде? Большое спасибо!
Мой плохой, я отредактировал код и забыл об этом. Завтра могу заменить, без проблем =)
@smokingpenguin Я поставил свой код в ответ с вашими файлами примеров плюс несколько примеров для проверки алфавитного порядка. Не стесняйтесь задавать вопросы, если что-то неясно в коде.
Спасибо. Теперь это имело такой смысл.
Для потомков на случай, если ссылка repl сгниет: gist.github.com/a-recknagel/1070f39f5bc7e460a6801c41e92e9f73
Продолжая комментарий, который я сделал выше:
Прочитайте оба файла и сохраните их строки в списке
Сгладить список
Сортировать список по представлениям в строке
Следовательно:
список.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
список2.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
ВЫХОД:
[
'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'
]
Более короткая версия:
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
я не могу использовать import glob, чтобы открыть эти два файла .txt?
подождите, где я могу увидеть, что путь?
@smokingpenguin Я имел в виду, что показал my
способ. и поскольку это не было задано / упомянуто в исходном вопросе, я попытался с этим.
Вы можете использовать следующий код:
#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']
Загляните в
sort()
/sorted()
.