List combination based on value of each index in another list

Question:

I have the following two lists

list_1 = [3, 5, 7, 2]

list_2 = [
          '1-CHA', '2-NOF', '3-INC',
          '4-CHA', '5-NOF', '6-NOF', '7-INC', '8-INC',
          '9-INC', '10-INC', '11-CHA', '12-NOF', '13-CHA', '14-CHA', '15-INC', 
          '16-INC', '17-INC'
         ]

I want to combine the two lists in the following way:

final_list = [
              '1-CHA|2-NOF|3-INC',
              '4-CHA|5-NOF|6-NOF|7-INC|8-INC',
              '9-INC|10-INC|11-CHA|12-NOF|13-CHA|14-CHA|15-INC',
              '16-INC|17-INC'
             ]

final_list – should have the same length as list_1

Asked By: Duvan Smuts

||

Answers:

You can create an iterator from list_2 so that you can fetch items from the list for the number of times specified in list_1 by calling next on the iterator:

seq = iter(list_2)
final_list = ['|'.join(next(seq) for _ in range(n)) for n in list_1]

You can also use itertools.islice instead to avoid repeated calls to next (thanks to @gog for the suggestion):

from itertools import islice
seq = iter(list_2)
final_list = ['|'.join(islice(seq, 0, n)) for n in list_1]

To do it without using list comprehension or generator expression, you can create an empty list and append items to it:

seq = iter(list_2)
final_list = []
for n in list_1:
    items = []
    for _ in range(n):
        items.append(next(seq))
    final_list.append('|'.join(items))

Demo: https://replit.com/@blhsing/BlandEssentialJavadoc

Answered By: blhsing

You could do it like this:

final_list = [
    # Join with a `|` pipe character
    '|'.join(
        # Slice list 2
        list_2[
            # Start at the sum of values less than i then sum of values including i
            sum(list_1[:i]):sum(list_1[:i+1])])
    for i in range(len(list_1))
]

On one line:

final_list = ['|'.join(list_2[sum(list_1[:i]):sum(list_1[:i+1])]) for i in range(len(list_1))]
Answered By: mousetail
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.