简体   繁体   中英

Split each list of lists into sublists of given lengths

I want to split each list of lists into sublists of given length. I have a courses array which looks like this:

[['CS105', 'ENG101', 'MATH101', 'GER', 'ENG102', 'CS230', 'MATH120', 'GER', 'CS205', 'FREE', 'GER', 'CS106', 'CS215', 'CS107', 'ENG204', 'GER', 'MATH220', 'CS300', 'CS206', 'CS306', 'GER', 'FREE', 'CS312', 'CS450', 'GER', 'CS321', 'FREE', 'CS325', 'GER', 'CS322', 'MAJOR', 'CS310', 'STAT205', '', 'CS443', 'CS412', 'CS421', 'GER', 'CS444', 'FREE', 'FREE','','',''], ['CS105', 'ENG101', 'MATH101', 'GER', 'ENG102', 'CS230', 'MATH120', 'GER', 'CS205', 'FREE', 'GER', 'CS106', 'CS215', 'CS107', 'ENG204', 'GER', 'MATH220', 'CS300', 'CS206', 'CS306', 'GER', 'FREE', 'CS312', 'CS450', 'GER', 'CS321', 'FREE', 'CS325', 'GER', 'CS322', 'MAJOR', 'CS310', 'STAT205', '', 'CS443', 'CS412', 'CS421', 'GER', 'CS444', 'FREE', 'FREE','','',''],...]

I want to split each list in sublists in and them to look like this:

[[['CS105', 'ENG101', 'MATH101', 'GER'],['ENG102', 'CS230', 'MATH120', 'GER'], ['CS205', 'FREE'], ['GER'], ['CS106', 'CS215', 'CS107','ENG204', 'GER'], ['MATH220', 'CS300', 'CS206', 'CS306'], ['GER', 'FREE'], ['CS312'], ['CS450', 'GER', 'CS321', 'FREE', 'CS325'], ['GER', 'CS322', 'MAJOR', 'CS310'], ['STAT205',''], [''], ['CS443', 'CS412', 'CS421', 'GER',''], ['CS444', 'FREE', 'FREE',''],['','']]...]

what I have done till now is the following:

schedule = [4, 4, 2, 1, 5, 4, 2, 1, 5, 4, 2, 1, 5, 4, 2, 1]
        for i in courses:
             Output = [courses[x - y: x] for x, y in zip(accumulate(schedule), schedule)]
        print(Output[0])

but what is printed with Output[0] is 4 lists in a row, so as I get it it takes pairs of 4 probably. schedule is the given lengths that I want each list to be splitted. I cannot understand how I need to loop probably in order to achieve the result I need.

Got a working piece of code for you:

new_list = []
for c in courses:
    _sum = 0
    _list = []
    for t in schedule:
        el = c[_sum:_sum + t]
        _sum += t
        _list.append(el)
    new_list.append(_list)

Probably can be done quicker but this should do the job!

Write me a message if you got any questions or it is not working properly. Hope I could help.

Here's a function that does what you want:

from itertools import accumulate

def divide_into_schedule(input_list, schedule):
    if schedule[0] != 0: 
        schedule.insert(0, 0) 
    indices = list(accumulate(schedule)) 
    output_list = [list() for _ in input_list] 
    for start_index, end_index in zip(indices, indices[1:]): 
        for input_sublist, output_sublist in zip(input_list, output_list): 
            output_sublist.append(input_sublist[start_index:end_index]) 
    return output_list

The core idea here is:

  • create a list of indices to take from each sublist by accumulating the schedule list;
  • initialize an output list with the same structure as the input list;
  • zip over the list of indices and the same list of indices with an element shifted ( indices[1:] ), so that the values become the start and end index to select from each sublist;
  • zip over each sublist in input_list and output_list ;
  • using the start/end indices, "copy-paste" the desired sub-sublist from input_list onto output_list .

Call it by passing the input list and schedule as such:

input_list = [['CS105', 'ENG101', 'MATH101', 'GER', 'ENG102', 'CS230', 'MATH120', 'GER', 'CS205', 'FREE', 'GER', 'CS106', 'CS215', 'CS107', 'ENG204', 'GER', 'MATH220', 'CS300', 'CS206', 'CS306', 'GER', 'FREE', 'CS312', 'CS450', 'GER', 'CS321', 'FREE', 'CS325', 'GER', 'CS322', 'MAJOR', 'CS310', 'STAT205', '', 'CS443', 'CS412', 'CS421', 'GER', 'CS444', 'FREE', 'FREE','','',''], ['CS105', 'ENG101', 'MATH101', 'GER', 'ENG102', 'CS230', 'MATH120', 'GER', 'CS205', 'FREE', 'GER', 'CS106', 'CS215', 'CS107', 'ENG204', 'GER', 'MATH220', 'CS300', 'CS206', 'CS306', 'GER', 'FREE', 'CS312', 'CS450', 'GER', 'CS321', 'FREE', 'CS325', 'GER', 'CS322', 'MAJOR', 'CS310', 'STAT205', '', 'CS443', 'CS412', 'CS421', 'GER', 'CS444', 'FREE', 'FREE','','',''],...]
schedule = [4, 4, 2, 1, 5, 4, 2, 1, 5, 4, 2, 1, 5, 4, 2, 1]
output_list = divide_into_schedule(input_list, schedule)

The result isn't exactly the same as your desired output due to the typos I mentioned in my comment, but I believe it does what you want.

Your original idea of using itertools.accumulate was actually quite good, you just made some small mistakes:

output = [ [sublist[x - y: x] for x, y in zip(accumulate(schedule), schedule)] for sublist in courses ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM