slicing lists

MRAB google at mrabarnett.plus.com
Thu May 8 14:04:29 EDT 2008


On May 8, 4:34 am, Yves Dorfsman <y... at zioup.com> wrote:
> Miles wrote:
> > On Wed, May 7, 2008 at 7:46 PM, Ivan Illarionov
> >  >  > Is there a way to do:
> >  >  > x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> >  >  > x[0,2:6]
>
> >  >  > That would return:
> >  >  > [0, 3, 4, 5, 6]
>
> Arg... Yes, this is a typo, I meant:
> [1, 3, 4, 5, 6]
>
> >  I think Yves meant to return [1, 3, 4, 5, 6], as in Perl's list slicing:
>
> >  my @x = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
> >  return @x[0, 2..6]; // returns (1, 3, 4, 5, 6)
>
> Yes, exactly.
>
>
>
> >  This isn't incredibly efficient, but it does what you want (I think):
>
> >  from itertools import chain
>
> >  class multisliceable(list):
> >   def __getitem__(self, slices):
> >     if isinstance(slices, (slice, int, long)):
> >       return list.__getitem__(self, slices)
> >     else:
> >       return list(chain(*[list.__getitem__(self, s) if isinstance(s, slice)
> >                           else [list.__getitem__(self, s)] for s in slices]))
>
> >  p = open('/etc/passwd')
> >  q = [multisliceable(e.strip().split(':'))[0,2:] for e in p]
>
> So would it be a worthy addition to python, to add it right in the core of
> the language, and hopefully in an efficient manner ?
>
> That would certainly help some type of list comprehensions, making them more
> readable, and hopefully more readable (running split once instead of twice,
> or how many number of time you need it). The passwd example is just one
> example I ran into, but I can see running in this problem a lot with more
> complex cases. Right now I solve the passwd pb with:
>
> p = file('/etc/passwd').readlines()
> r = [ e.strip().split(':') for e in p ]
> s = [  e[0:1] + e[2:]   for e in r ]
>
> Or:
>
> p = file('/etc/passwd').readlines()
> s = [  e.strip().split(':')[0:1] + e.strip().split(':')[2:]   for e in p ]
>
> In the first case we're looping twice (two list comprehension), in the
> second case we're running the split twice on every element of p.
>
You should've read the thread entitled "Why don't generators execute
until first yield?"! :-) Michael Torrie gave the URL
http://www.dabeaz.com/generators/Generators.pdf. Your example can be
rewritten as follows:

p = file('/etc/passwd') # No need for readlines() because file's
iterator yields the lines.
r = ( e.strip().split(':') for e in p ) # A generator expression
instead of a list comprehension.
s = [  e[0:1] + e[2:]   for e in r ]



More information about the Python-list mailing list