Question:
Hello, the task is as follows:
There are 2 txt files (the number of lines in each is arbitrary). It is necessary to insert lines from one list into another at a certain interval, for example, every n lines.
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))
In case you ask
while i + n <= len(list2):
list2 – the file from where we take the lines for substitution, the code works as it should.
However, with
while i + n <= len(list1):
I get the error:
list1.insert(i * n, list2[i])
IndexError: list index out of range
I ask you to suggest how to implement the substitution of lines from list2 if there are fewer lines in list2 than in list1. That is, when the lines in list2 run out, line substitution must again start at 0 in 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
In this case, it is important that the lines are substituted exactly from list2 into list1. And when the lines in list2 run out, they should start substituting again from element 0.
Answer:
You can itertools.cycle()
keep items in a circle (starting with the first one after the end).
To traverse multiple elements at once, you can apply the zip(*[iterator]*n)
idiom.
To alternate groups from the first iterator with elements from the second and return a flat version (no recursion) and truncate the input to the shorter length of the arguments:
import itertools
flatten = itertools.chain.from_iterable
def interlaced(groups, items):
return flatten(itertools.chain(group, [item]) for group, item in zip(groups, items))
By combining:
n = 3
lines = interlaced(zip(*[itertools.cycle(f1)]*(n-1)), f2)
output_file.writelines(lines)
Example:
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