Issue
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 & 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(":")]
for indice_set in slicing_str.strip("[]").split(",")
]
# Handle Ellipsis "..."
indices = [
... if index_slice == ["..."] else index_slice for index_slice in indices
]
# Handle "None" values
indices = [
None if index_slice == ["None"] 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("-").isdigit()
else index_slice
for index_slice in indices
]
# Create indice slicing list
indices = [
slice(*[int(i) if i and i.lstrip("-").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("[None, :1, 3:4, 2, :, 2:, ...]")
print(out)
# out:
# [None, slice(None, 1, None), slice(3, 4, None), 2, slice(None, None, None), slice(2, None, None), Ellipsis]
Solution
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.
Answered By - Michael Szczesny
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.