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