Split a list into sub-lists based on index ranges

Question:

How do I split a list into sub-lists based on index ranges?

e.g. original list:

list1 = [x,y,z,a,b,c,d,e,f,g]

using index ranges 0–4:

list1a = [x,y,z,a,b]

using index ranges 5–9:

list1b = [c,d,e,f,g]

I already known the (variable) indices of list elements which contain certain string and want to split the list based on these index values.

Also need to split into variable number of sub-lists, i.e.:

list1a
list1b
.
.
list1[x]
Asked By: 2one

||

Answers:

list1a=list[:5]
list1b=list[5:]
Answered By: no1

In python, it’s called slicing. Here is an example of python’s slice notation:

>>> list1 = ['a','b','c','d','e','f','g','h', 'i', 'j', 'k', 'l']
>>> print list1[:5]
['a', 'b', 'c', 'd', 'e']
>>> print list1[-7:]
['f', 'g', 'h', 'i', 'j', 'k', 'l']

Note how you can slice either positively or negatively. When you use a negative number, it means we slice from right to left.

Answered By: TerryA
list1=['x','y','z','a','b','c','d','e','f','g']
find=raw_input("Enter string to be found")
l=list1.index(find)
list1a=[:l]
list1b=[l:]
Answered By: no1

If you already know the indices:

list1 = ['x','y','z','a','b','c','d','e','f','g']
indices = [(0, 4), (5, 9)]
print [list1[s:e+1] for s,e in indices]

Note that we’re adding +1 to the end to make the range inclusive…

Answered By: Jon Clements

Note that you can use a variable in a slice:

l = ['a',' b',' c',' d',' e']
c_index = l.index("c")
l2 = l[:c_index]

This would put the first two entries of l in l2

Answered By: Mark R. Wilkins

Consider the core pesudocode of the following example:

def slice_it(list_2be_sliced, indices):
    """Slices a list at specific indices into constituent lists.
    """
    indices.append(len(list_2be_sliced))
    return [list_2be_sliced[indices[i]:indices[i+1]] for i in range(len(indices)-1)]
Answered By: Shady

One of the ways to do it if you have multiple indexes or know the range of indexes you need to get:

split_points – points where you will split your string or list

k – the range you need to split, example = 3

split_points = [i for i in range(0, len(string), k)]

parts = [string[ind:ind + k] for ind in split_points]
Answered By: Milana

This is the way I do it, if the input is a list of indices on which to split an array:

#input
list1 = ['x','y','z','a','b','c','d','e','f','g']
split_points = [2,5,8] 

#split array on indices:
s = split_points+[len(list1)]  #must contain index beyond last element, alternatively use directly split_points.append(len(list1))
print([list1[i1:i2] for i1,i2 in zip([0]+s[:-1],s)])

>>> [['x', 'y'], ['z', 'a', 'b'], ['c', 'd', 'e'], ['f', 'g']]
Answered By: Vincenzooo

Update Apr. 2023: Thank you Donna for your comment! I did some changes, like you suggested, but i think that it’s a pretty easy example to have more precise information how it works.

It’s better to use SequenceT instead of Sequence ’cause then later you can complement the variables with proper commands depending of the Sequence-types ‘list’ or ‘tuple’ (E.g.: append to a list)

from collections.abc import Sequence
from typing import TypeVar

SequenceT = TypeVar('SequenceT', bound=Sequence)

def slice_in_2(seq: SequenceT, index: int) -> tuple[SequenceT, SequenceT]:
    return seq[:index], seq[index:]

def slice_in_N(seq: SequenceT, indexes: Sequence[int]) -> list[SequenceT]:
    previous_i = 0
    seq2 = result = []
    for i in indexes:
        seq2 = slice_in_2(seq, i-previous_i)
        result.append(seq2[0])
        seq = seq2[1]
        previous_i = i
    result.append(seq2[1])
    return result

t = (1, 2, 3, 4, 5)
print(slice_in_2(t, 3)) # Output: ((1, 2, 3), (4, 5))
print(slice_in_N(t, (2,3))) # Output: [(1, 2), (3,), (4, 5)]
        
Answered By: Practical
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.