Join adjacent list elements as long as condition is met in Python

Viewed 134

I have two lists

list1 = [577, 553, 613, 673, 773, 827, 923, 963, 993, 1049, 1117, 1153, 1173, 1183]
list2 = ['Al,', 'Alan', 'Latin', 'Amer', '2', 'P', '1', 'vo', '|', '1', 't', '|', '2', 'Avg']

If the difference between list1 adjacent elements is < 75 keep joining corresponding elements in list2 until condition met, if condition fails current element to the output and move on

Output is like

['Al, Alan Latin Amer', '2 P', '1 vo | 1 | 2 Avg']

I have tried the below logic but its just joining only two elements

for i in list2:
    indx_val = list2.index(i)
    if indx_val !=0:
        if list1[indx_val] - list1[indx_val-1] < 75:
            list2[indx_val - 1] = list2[indx_val -1] +' '+ list2[indx_val]
            list1.pop(indx_val)
            list2.pop(indx_val)

And giving output as

['Al, Alan', 'Latin Amer', '2 P', '1 vo', '| 1', 't |', '2 Avg']

can you please help me in getting the output as below?, Thanks in advance

['Al, Alan Latin Amer', '2 P', '1 vo | 1 | 2 Avg']
7 Answers

By looping over list1:

list1 = [577, 553, 613, 673, 773, 827, 923, 963, 993, 1049, 1117, 1153, 1173, 1183]
list2 = ['Al,', 'Alan', 'Latin', 'Amer', '2', 'P', '1', 'vo', '|', '1', 't', '|', '2', 'Avg']
res = [list2[0]]

for i in range(1, len(list1)):
    if abs(list1[i] - list1[i-1]) < 75:
        res[-1] = res[-1]+" " + list2[i]
    else:
        res.append(list2[i])

print(res)

output:

['Al, Alan Latin Amer', '2 P', '1 vo | 1 t | 2 Avg']

You could try this for loop:

newlist = []
s = list2[0] + ' '
for i, (x, y) in enumerate(zip(list1, list1[1:])):
    if (y - x) < 75:
        s += list2[i + 1] + ' '
    else:
        newlist.append(s.rstrip())
        s = list2[i + 1] + ' '
newlist.append(s.rstrip())
print(newlist)

Output:

['Al, Alan Latin Amer', '2 P', '1 vo | 1 t | 2 Avg']

You can keep iterating through the elements till the absolute difference between adjacent elements is less than 75; Once it isn't, append the sublist that satisfied our constraint.

list1 = [577, 553, 613, 673, 773, 827, 923, 963, 993, 1049, 1117, 1153, 1173, 1183]
list2 = ['Al,', 'Alan', 'Latin', 'Amer', '2', 'P', '1', 'vo', '|', '1', 't', '|', '2', 'Avg']

result = []

i = 0
while i < len(list1):
    j = i
    while j < len(list1) and abs(list1[j] - list1[i]) < 75:
        j += 1
    result.append(" ".join(list2[i:j+1]))
    i = j

print(result)

Output: ['Al, Alan Latin Amer', 'Amer 2', '2 P 1', '1 vo | 1', '1 t |', '| 2 Avg']

Provided the both list have the same length... zip them

diff = [j-i for i, j in zip(list1[:-1], list1[1:])]
output = [list2[0]]

for d, s in zip(diff, list2[1:]):
   if d <75:
      output[-1] = f'{output[-1]}  {s}'
   else:
      output += [s]

print(output)

Output

['Al,  Alan  Latin  Amer', '2  P', '1  vo  |  1  t  |  2  Avg']

Try this:

list1 = [577, 553, 613, 673, 773, 827, 923, 963, 993, 1049, 1117, 1153, 1173, 1183]
list2 = ['Al,', 'Alan', 'Latin', 'Amer', '2', 'P', '1', 'vo', '|', '1', 't', '|', '2', 'Avg']

indices=[0]+[i for i in range(1,len(list1)) if list1[i]-list1[i-1]>75]+[len(list2)] #====  Detect where the difference is >75. Add [0] and [len(list)] as the first and the last index to slice

list3=[' '.join(list2[indices[i]:indices[i+1]]) for i in range(len(indices)-1)]
print(list3) #==== Join list slices

You can iterate over list1 to find the slicing indices. Use zip to iterate over pairs of each value and the next value

indices = []
for (x, y, i) in zip(list1, list1[1:], range(len(list1))):
    if abs(x - y) > 75:
        indices.append(i + 1)
print(indices) # [4, 6]

After that you can use those indices to slice list2

result = []
for start, end in zip([0] + indices, indices + [len(list2)]):
    result.append(' '.join(list2[start:end]))
print(result) # ['Al, Alan Latin Amer', '2 P', '1 vo | 1 t | 2 Avg']

With list comprehensions

indices = [i + 1 for (x, y, i) in zip(list1, list1[1:], range(len(list1))) if abs(x - y) > 75]
result = [' '.join(list2[start:end]) for start, end in zip([0] + indices, indices + [len(list2)])]

As an exercise, I've tried to resolve using reduce. finally, it is not very readable, but maybe the fastest solution

from functools import reduce
list1 = [577, 553, 613, 673, 773, 827, 923, 963, 993, 1049, 1117, 1153, 1173, 1183]
list2 = ['Al,', 'Alan', 'Latin', 'Amer', '2', 'P', '1', 'vo', '|', '1', 't', '|', '2', 'Avg']

def r(prev,curr):
    #print(prev,curr)
    
    prev_val, ret = prev
    cur_val, key = curr
    if prev_val is None:
        ret =  [[key]]
    elif abs(cur_val-prev_val)<75:
        ret[-1].append(key)
    else:
        ret.append([key])
    return cur_val, ret
        
    
[' '.join(x) for x in reduce( r, zip(list1,list2), (None,None))[1]]

#['Al, Alan Latin Amer', '2 P', '1 vo | 1 t | 2 Avg']
Related