Merge python list by specific indexes

I have an array, where I want a specific index to be merged.

["captain:", "robot", "alpha", "beta:", "gama", "delta:", "fighter", "test", "exp"]

the idea of this, every even element should contain : and the rest of the elements should not contain :

The output I want:

["captain:", "robot, alpha", "beta:", "gama", "delta:", "fighter, test, exp"]

considering the array is changeable, for example, the array could be:

["captain:", "robot", "beta:", "game", "exp", "delta:", "fighter", "test"]

the output should be the same, each even with : and odd index without :

Can anyone help, please?


Solution 1:

Here's an implementation using groupby:

import itertools
x = ["captain:", "robot", "alpha", "beta:", "gama", "delta:", "fighter", "test", "exp"]
new_list = []
for key, group in itertools.groupby(x, key = lambda string: string.endswith(':')):
    if key: # in case you happen to consecutive values that end in a colon
        new_list += list(group)
    else: # these elements do not end in a colon
        new_list.append(', '.join(group))
print(new_list)
# ['captain:', 'robot, alpha', 'beta:', 'gama', 'delta:', 'fighter, test, exp']

Here, the grouping key checks to see if the item ends in a ":", if it does, key is True, otherwise it is False. If consecutive values of key are the same, they are put in the same group. Thus, any number of elements following a string containing a colon will be grouped together.

Solution 2:

itertools.groupby() has you covered.

lst = ["captain:", "robot", "alpha", "beta:", "gama", "delta:", "fighter", "test", "exp"]
print([', '.join(g[1]) for g in itertools.groupby(lst, lambda s: s.endswith(':'))]) 
# ['captain:', 'robot, alpha', 'beta:', 'gama', 'delta:', 'fighter, test, exp']

Solution 3:

I did not know about the groupby function. So, here is an alternative approach, in case anyone was interested:

sample = ["captain:", "robot", "alpha", "beta:", "gama", "delta:", "fighter", "test", "exp"]


def find_next_index(sample, start):
    for i in range(len(sample)):
        if i>start and ":" in sample[i]:
            return i, ", ".join(sample[start+1:i]), False
    
    return start, ", ".join(sample[start+1:]), True


result = []
start = 0
while True:
    x,y,z = find_next_index(sample, start)

    result.append(sample[start])
    result.append(y)
    start = x
    if z:
        break
    

print(result)

Output:

['captain:', 'robot, alpha', 'beta:', 'gama', 'delta:', 'fighter, test, exp']