Python3 использует генератор для фильтрации файла с многострочными записями

Мне нужно читать огромные файлы, структурированные как многострочные записи, и записывать в файл записи с определенными индексами, скажем, номера записей R = 1, 2 и 1093. Если каждая запись состоит из N = 3 строк, это равносильно чтению файла построчно, а затем записи строк с номерами 1, 2, 3 и 4, 5, 6 и 3277, 3278, 3279 (в том смысле, что первая строка в каждой записи Ri начинается по номеру строки Ri-1*N+1.

Я предполагаю, что можно рассчитать строки для записи и просмотреть файл строка за строкой и записать эти строки. Однако возможно ли «заархивировать» последовательные строки 1, 2 и 3 в объект генератора, содержащий записи, и каким-то образом отфильтровать их или распечатать их непосредственно в файл, если они перечисляются в R ? Что-то в этом псевдокоде:

def subset(file_in, file_out, N, R):
    with open(file_in, "rt") as fin, open(file_out, "wt") as fout:
        line = (line.rstrip() for line in fin)
        record = enumerate(zip(line, line, line)) # What if records are of size N
        for i, r in record if i in R:
            fout.write(r)

Что делать, если вы хотите, чтобы размер записи N был параметром?

ПРИМЕР ОБНОВЛЕНИЯ

Пример для file_in (4 записи, 3 строки/запись):

dslfkj
2
a
dflkj
3
g
fds
2
b
fsdlkj
1
n

Тогда подмножество (file_in, file_out, 3, [1,3]) даст (file_out)

dslfkj
2
a
fds
2
b

XY проблема. вам не нужно группировать или собирать эти строки, чтобы иметь возможность получить этот вывод.

Paritosh Singh 29.05.2019 14:05

Нет, тогда мне нужно будет рассчитать строки для печати (как упоминалось во вступлении к моему вопросу), верно?

user3375672 29.05.2019 14:06

ммм, это определенно самое чистое.

Paritosh Singh 29.05.2019 14:07
stackoverflow.com/questions/51969335/… ... Как насчет этого?
รยקคгรђשค 29.05.2019 14:32

Возможный дубликат Итерировать N элементов за раз на генераторе с одним выходом

รยקคгรђשค 29.05.2019 14:34

@Suparshva Я думаю, что конкретные записи не выбираются (но я мог неправильно прочитать этот пост.

user3375672 29.05.2019 15:03

@ user3375672 из вашего кода вы, кажется, получаете n строк за раз (которые вы считаете записью ... первые n строк записывают 1, следующие n строк записывают 2 и так далее) ... теперь вам нужны конкретные записи, скажем, 1, 3 7 (поправьте меня, если я неправильно понял) ... поэтому, как только у вас есть генератор, как в ответе, вы можете иметь другой генератор, который дает эти записи 1,3 и 7 (возьмите его как входной список) ... номер записи, который вы можете отслеживать, сколько раз вы выполняли выход на первый генератор ... ваш вопрос задавался "Что делать, если вы хотите, чтобы размер записи N был параметром?"

รยקคгรђשค 29.05.2019 19:48
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Для этой задачи имеет смысл просто решить ее непосредственно построчно, используя деление по этажам.

Например:

fin = '''
dslfkj
2
a
dflkj
3
g
fds
2
b
fsdlkj
1
'''

line_gen = (line.rstrip() for line in fin.strip().split())

R = [1, 3]
R = [val - 1 for val in R] #zero indexing
N = 3
for i, line in enumerate(line_gen):
    if i // N in R:
        print(line)

Выход:

dslfkj
2
a
fds
2
b

Ваша функция может выглядеть примерно так: (вы можете проверить, работает ли она «из коробки» или требует настроек. Я не проверял часть открытия файла.

def subset(file_in, file_out, N, R):
    R = [val - 1 for val in R] #zero indexing
    with open(file_in, "rt") as fin, open(file_out, "wt") as fout:
        line_gen = (line.rstrip() for line in fin)
        for i, line in enumerate(line_gen):
            if i // N in R:
                fout.write(line)
                fout.write('\n')

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

Старый ответ:

Вы можете создать n ссылки на объект с помощью списка, а затем распаковать с помощью файла * (также известный как знак) оператор.

Например:

from itertools import zip_longest
line = (x for x in range(100, 132))
n = 3
record = zip(*([line] * n)) #equivalent to *[line, line, line] which is unpacked into zip arguments
for i, r in enumerate(record):
    print(i, r)

0 (100, 101, 102)
1 (103, 104, 105)
2 (106, 107, 108)
3 (109, 110, 111)
4 (112, 113, 114)
5 (115, 116, 117)
6 (118, 119, 120)
7 (121, 122, 123)
8 (124, 125, 126)
9 (127, 128, 129)

Кроме того, в зависимости от того, что вы хотите сделать для «остаточных» строк, вы можете вместо этого использовать zip_длиннейший.

Точно - возможно, вашей функции нужна новая строка в write()

user3375672 29.05.2019 15:41

Чуть аккуратнее, пожалуй, с одной строкой print(line, file = fout)

user3375672 31.05.2019 09:31

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