Страницы

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

воскресенье, 2 февраля 2020 г.

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

#python_3x #list


Здравствуйте, стоит следующая задача:

Есть 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 элемента.
    


Ответы

Ответ 1



Чтобы элементы по кругу возвращались (начинались с первого по окончанию), можно 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

Ответ 2



Воспользуйтесь модулем itertools: In [1]: l1 = [1,2,3,4] In [2]: l2 = list('abcde') In [3]: from itertools import zip_longest, chain, cycle In [4]: list(chain.from_iterable(zip(cycle(l1), l2))) Out[4]: [1, 'a', 2, 'b', 3, 'c', 4, 'd', 1, 'e']

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

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