How do I more efficiently convert a string of slices to slice objects that can then be used to slice arrays & tensors in PyTorch / NumPy?
How can I simplify this function that converts strings of slices for PyTorch / NumPy to slice list objects that can then be used to slice arrays &amp; tensors?
The code below works, but it seems rather inefficient in terms of how many lines it takes.
def str_to_slice_indices(slicing_str: str):
    # Convert indices to lists
    indices = [
        [i if i else None for i in indice_set.strip().split(&quot;:&quot;)]
        for indice_set in slicing_str.strip(&quot;[]&quot;).split(&quot;,&quot;)
    ]

    # Handle Ellipsis &quot;...&quot;
    indices = [
        ... if index_slice == [&quot;...&quot;] else index_slice for index_slice in indices
    ]
    # Handle &quot;None&quot; values
    indices = [
        None if index_slice == [&quot;None&quot;] else index_slice for index_slice in indices
    ]
    # Handle single number values
    indices = [
        int(index_slice[0])
        if isinstance(index_slice, list)
        and len(index_slice) == 1
        and index_slice[0].lstrip(&quot;-&quot;).isdigit()
        else index_slice
        for index_slice in indices
    ]

    # Create indice slicing list
    indices = [
        slice(*[int(i) if i and i.lstrip(&quot;-&quot;).isdigit() else None for i in index_slice])
        if isinstance(index_slice, list)
        else index_slice
        for index_slice in indices
    ]
    return indices

Running the above function with an example covering the various types of inputs, give this:
out = str_to_slice_indices(&quot;[None, :1, 3:4, 2, :, 2:, ...]&quot;)
print(out)

# out:
# [None, slice(None, 1, None), slice(3, 4, None), 2, slice(None, None, None), slice(2, None, None), Ellipsis]


Iterating multiple times is not necessary. The sample string has been slightly expanded to test more cases.
def str2slices(s):
    d = {True: lambda e: slice(*[int(i) if i else None for i in e.split(':')]),
        'None': lambda e: None,
        '...': lambda e: ...}
    return [d.get(':' in e or e.strip(), lambda e: int(e))(e.strip()) for e in s[1:-1].split(',')]

str2slices('[None, :1, 3:4, 2, :, -10: ,::,:4:2, 1:10:2, -32,...]')

Output
[None,
 slice(None, 1, None),
 slice(3, 4, None),
 2,
 slice(None, None, None),
 slice(-10, None, None),
 slice(None, None, None),
 slice(None, 4, 2),
 slice(1, 10, 2),
 -32,
 Ellipsis]

The same errors as in OP's solution are caught. They don't silently change the result, but throw a ValueError for unsupported input.

Breakdown of the solution
Assuming string slicing and the split function are known.
With example
s = '[None, :1, 3:4, 2, :, -10: ,::,:4:2, 1:10:2, -32,...]'

we can find slices with
[':' in e for e in s[1:-1].split(',')]
#[False, True, True, False, True, True, True, True, True, False, False]

Using or short-circutting we can distinguish other cases
[':' in e or e.strip() for e in s[1:-1].split(',')]
#['None', True, True, '2', True, True, True, True, True, '-32', '...']

This values can be used as keys of a dictionary
d = {True: 'slice', 'None': None, '...': ...}
[d[':' in e or e.strip()] for e in s[1:-1].split(',')]
#KeyError: '2'

To prevent the KeyError we can use the get method with a default value.
d = {True: 'slice', 'None': None, '...': ...}
[d.get(':' in e or e.strip(), 'number') for e in s[1:-1].split(',')]
#[None, 'slice', 'slice', 'number', 'slice', 'slice', 'slice', 'slice', 'slice', 'number', Ellipsis]

In order to process slices, we need to parse additional values ​​at runtime. So we use lambdas as dictionary values ​​to be able to call them with (e.strip()). Finally, we convert values ​​to int if necessary.
d = {True: lambda e: slice(*[int(i) if i else None for i in e.split(':')]),
    'None': lambda e: None,
    '...': lambda e: ...}
[d.get(':' in e or e.strip(), lambda e: int(e))(e.strip()) for e in s[1:-1].split(',')]

Output
[None,
 slice(None, 1, None),
 slice(3, 4, None),
 2,
 slice(None, None, None),
 slice(-10, None, None),
 slice(None, None, None),
 slice(None, 4, 2),
 slice(1, 10, 2),
 -32,
 Ellipsis]

