Страницы

Поиск по вопросам

среда, 3 апреля 2019 г.

Вставить элементы одного списка в другой с определённым шагом

Здравствуйте, стоит следующая задача:
Есть 2 txt файла (количество строк в каждом произвольно). Необходимо строки из одного списка вставить в другой через определённый интервал, например, через каждые n строк.
f1 = open(r'c:\Исходная база.txt') f2 = open(r'c:\Строки для добавления.txt') list1 = f1.readlines() list2 = f2.readlines() f1.close() f2.close() i = 0 n = 2 while i + n <= 10: list1.insert(i * n, list2[i]) i = i + 1 with open(r'c:\результат.txt', 'w') as res: for item in list1: res.write("{}".format(item))
В случае, если задать
while i + n <= len(list2):
list2 - файл откуда берём строки для подстановки, код работает как надо.
Однако, при
while i + n <= len(list1):
Получаю ошибку:
list1.insert(i * n, list2[i])
IndexError: list index out of range
Прошу подсказать как реализовать подстановку строк из list2 в случае, если строк в list2 меньше, чем в list1. То есть когда строки в list2 кончатся, подстановка строк должна опять начаться с 0 элемента list2.
Исходные данные list1: 1, 2, 3, 4, .., m Исходные данные List2: a, b, c, d, .., k Результат должен быть: 1, a, 2, b, 3, c ... при n=2 1, 2, a, 3, 4, b, .. при n=3
При этом важно, чтобы строки подставлялись именно из list2 в list1. И когда строки в list2 кончатся, они должны опять начать подставляться с 0 элемента.


Ответ

Чтобы элементы по кругу возвращались (начинались с первого по окончанию), можно itertools.cycle() использовать.
Чтобы по несколько элементов сразу обходить, можно zip(*[iterator]*n) идиому применить.
Чтобы чередовать группы из первого итератора с элементами из второго и вернуть плоскую версию (без рекурсии) и обрезая ввод по меньшей длине аргументов:
import itertools
flatten = itertools.chain.from_iterable
def interlaced(groups, items): return flatten(itertools.chain(group, [item]) for group, item in zip(groups, items))
Объединяя :
n = 3 lines = interlaced(zip(*[itertools.cycle(f1)]*(n-1)), f2) output_file.writelines(lines)
Пример:
f1 = iter([1,2,3,4]) f2 = iter("abcde") it = interlaced(zip(*[itertools.cycle(f1)]*(n-1)), f2) print(*it) # -> 1 2 a 3 4 b 1 2 c 3 4 d 1 2 e

Комментариев нет:

Отправить комментарий