The goal is to insert a string after every other element in the list apart from the last one:
arr0 = ['aa','bb','cc','dd']
Goal
['aa','XX','bb', 'XX','cc','XX','dd']
This topic has been addressed in posts like this, but the lists of strings used are only one character in length which affects the list comprehension. I do not have enough reputation points to comment and ask for clarification.
I have implemented it with a for loop, but I was trying to practice with list-comprehension and would appreciate insight as to where I am going wrong with it. Currently getting a SyntaxError: invalid syntax
.
Example and Current Implementation
arr0 = ['aa','bb','cc','dd'] # Goal ['aa','XX','bb', 'XX','cc','XX','dd']
# Stop for range
total = len(arr0)*2-1
for i in range(1, total, 2):
arr0.insert(i, "XX")
# Returns ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
[el for y in [[el, 'XX'] if idx != len(arr0)-1 else el for idx, el in enumerate(arr0)] for el in y if isinstance(y, list) else el]
Breakdown
[[el, 'XX'] if idx != len(arr0)-1 else el for idx, el in enumerate(arr0)]
# Returns
# [['aa', 'XX'], ['bb', 'XX'], ['cc', 'XX'], 'dd']
In the outer comprehension, I am trying to return it as a single list of the strings. I am trying to use isinstance
to check if the element is a list or not (the last item being a string) and if not return simply the string.
I really appreciate the responses. I should have included this alternative case that I do encounter where I do not want elements inserted after a 'Note' element at the end, in which case I could not perform the slice. Is negative indexing with a step possible?
# Alternative scenario
arr1 = ['aa','bb','cc','dd', 'Note']
# ['aa','XX,'bb','XX,'cc','XX,'dd','Note']
You can simply use a nested list comprehension and strip the last element:
>>> [e for i in arr0 for e in [i, "XX"]][:-1]
['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
You can also use a .split()
/.join()
trick (which is probably less performant):
>>> ",XX,".join(arr0).split(",")
['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
A fancier way is to use itertools.chain
:
>>> from itertools import chain
>>> list(chain.from_iterable(zip(arr0, ["XX"]*len(arr0))))[:-1]
['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
Edit: For the alternative case added later to the question, it is possible to slice the input and manually append the last element to the output:
>>> arr1 = ['aa','bb','cc','dd', 'Note']
>>> [e for i in arr1[:-1] for e in [i, "XX"]][:-1] + [arr1[-1]]
['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd', 'Note']