Creating slice notation from string

Bob van der Poel bob at mellowood.ca
Thu Sep 3 18:29:02 CEST 2009


On Sep 2, 8:52 pm, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
> On Wed, 02 Sep 2009 17:32:09 -0700, Bob van der Poel wrote:
>
> > Actually, nither this or Jan's latest is working properly. I don't know
> > if it's the slice() function or what (I'm using python 2.5). But:
>
> > x = [1,2,3,4,5]
> > slice_string="2"
> > items = [int(n) if n else None for n in slice_string.split(":")]
> > [slice(*items)]
> > [1, 2]
>
> It's not clear what is input and what is output. I'm *guessing* that the
> first four lines are input and the fifth is output.
>
> By the way, nice catch for the "else None". But why are you wrapping the
> call to slice() in a list in the fourth line?
>
> I can't replicate your results. I get the expected results:
>
> >>> slice_string="2"
> >>> items = [int(n) if n else None for n in slice_string.split(":")]
> >>> [slice(*items)]
>
> [slice(None, 2, None)]
>
> exactly the same as:
>
> >>> slice(2)
>
> slice(None, 2, None)
>
> Testing this, I get the expected result:
>
> >>> x = [1,2,3,4,5]
> >>> x[slice(*items)]
>
> [1, 2]
>
> which is exactly the same if you do this:
>
> >>> x[:2:]
>
> [1, 2]
>
> > not the expected:
>
> > [3]
>
> Why would you expect that? You can't get that result from a slice based
> on 2 only. Watch:
>
> >>> x[2::]
> [3, 4, 5]
> >>> x[:2:]
> [1, 2]
> >>> x[::2]
>
> [1, 3, 5]
>
> There is no slice containing *only* 2 which will give you the result you
> are asking for. You would need to do this:
>
> >>> x[2:3]
>
> [3]
>
> Perhaps what you are thinking of is *indexing*:
>
> >>> x[2]
>
> 3
>
> but notice that the argument to list.__getitem__ is an int, not a slice,
> and the result is the item itself, not a list.
>
> To get the behaviour you want, you need something more complicated:
>
> def strToSlice(s):
>     if ':' in s:
>         items = [int(n) if n else None for n in s.split(':')]
>     else:
>         if s:
>             n = int(s)
>             items = [n, n+1]
>         else:
>             items = [None, None, None]
>     return slice(*items)
>
> > Things like -1 don't work either.
>
> They do for me:
>
> >>> slice_string="2:-2"
> >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> >>> items = [int(n) if n else None for n in slice_string.split(":")]
> >>> x[ slice(*items) ]
> [3, 4, 5, 6, 7, 8]
> >>> x[2:-2]
>
> [3, 4, 5, 6, 7, 8]
>
> > I'm really not sure what's going on, but I suspect it's the way that
> > slice() is getting filled when the slice string isn't a nice one with
> > each ":" present?
>
> I think you're confused between __getitem__ with a slice argument and
> __getitem__ with an int argument.
>
> --
> Steven

Yes, you're right ... I'm confused on what results I expect! Sorry
about that ... now that another day has passed it's all a bit more
clear.

I need to print out a number of these messages and write some test
code.

Thanks.



More information about the Python-list mailing list