slicing lists

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Yves Dorfsman

    slicing lists

    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]

    I am surprised this notation is not supported, it seems intuitive.
    A concrete example of the sort of thing I want to do:

    p = file('/etc/passwd').readli nes()
    q = [ e.strip().split (':')[0,2:] for e in p ]

    (getting rid of the password / x field)


    Thanks.

    Yves.
    Calgary AIX Linux UNIX React TypeScript JavaScript python contractor consultant programmer Yves Dorfsman


  • Ivan Illarionov

    #2
    Re: slicing lists

    On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
    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]
    IMHO this notation is confusing.

    What's wrong with:
    [0]+x[2:6]
    I am surprised this notation is not supported, it seems intuitive. A
    concrete example of the sort of thing I want to do:
    >
    p = file('/etc/passwd').readli nes()
    q = [ e.strip().split (':')[0,2:] for e in p ]
    >
    (getting rid of the password / x field)
    This works and is clearer:
    [[0] + e.strip().split (':')[2:] for e in open('/etc/passwd')]

    --
    Ivan

    Comment

    • Ivan Illarionov

      #3
      Re: slicing lists

      On Wed, 07 May 2008 23:46:33 +0000, Ivan Illarionov wrote:
      On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
      >
      >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]
      >
      IMHO this notation is confusing.
      >
      What's wrong with:
      [0]+x[2:6]
      >
      >I am surprised this notation is not supported, it seems intuitive. A
      >concrete example of the sort of thing I want to do:
      >>
      >p = file('/etc/passwd').readli nes()
      >q = [ e.strip().split (':')[0,2:] for e in p ]
      >>
      >(getting rid of the password / x field)
      >
      This works and is clearer:
      [[0] + e.strip().split (':')[2:] for e in open('/etc/passwd')]
      or maybe you wanted to do this:
      >>[e.split(':')[0] for e in open('/etc/passwd')]
      ['root', 'daemon', 'bin', 'sys', 'sync', ...]

      What are you trying to get from /etc/passwd?

      --
      Ivan

      Comment

      • castironpi@gmail.com

        #4
        Re: slicing lists

        On May 7, 6:58 pm, Ivan Illarionov <ivan.illario.. .@gmail.comwrot e:
        On Wed, 07 May 2008 23:46:33 +0000, Ivan Illarionov wrote:
        On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
        >
        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]
        >
        IMHO this notation is confusing.
        >
        What's wrong with:
        [0]+x[2:6]
        >
        I am surprised this notation is not supported, it seems intuitive. A
        concrete example of the sort of thing I want to do:
        >
        p = file('/etc/passwd').readli nes()
        q = [ e.strip().split (':')[0,2:] for e in p ]
        >
        (getting rid of the password / x field)
        >
        This works and is clearer:
        [[0] + e.strip().split (':')[2:] for e in open('/etc/passwd')]
        >
        or maybe you wanted to do this:
        >
        >[e.split(':')[0] for e in open('/etc/passwd')]
        >
        ['root', 'daemon', 'bin', 'sys', 'sync', ...]
        >
        What are you trying to get from /etc/passwd?
        >
        --
        Ivan- Hide quoted text -
        >
        - Show quoted text -
        The t. Oughtn't there be a run on Guido's name more often than is?

        You -could- write:

        x[ slice(0)+slice( 2,6) ]

        where slice would be an 'autochaining' type under a syntax. Fine for
        slices, not for logic.

        x[ b1+And+b2+Or+b3 ]

        would also register as b1 and b2 or b3, which really quickly rises on
        the wheel again, er, um, crawls up the spout.

        Would you be happy with x[ '0,2:6' ], necessarily in quotes? With two
        punctuation marks you couldn't get much farther in money than Python
        does today.

        x[ '0 2:6' ]
        -x.__getitem__( x, '0 2:6' )
        -'0 2:6'.split( )
        -x.__getslice__( x, slice( 0 ) )
        ... + x.__getslice__( x, slice( 2, 6 ) )

        However, it's not clear it's trivial to overwrite a built-in type's
        __getitem__!

        Comment

        • Miles

          #5
          Re: slicing lists

          On Wed, May 7, 2008 at 7:46 PM, Ivan Illarionov
          <ivan.illariono v@gmail.comwrot e:
          On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
          >
          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]
          >
          IMHO this notation is confusing.
          >
          What's wrong with:
          [0]+x[2: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)

          This isn't incredibly efficient, but it does what you want (I think):

          from itertools import chain

          class multisliceable( list):
          def __getitem__(sel f, slices):
          if isinstance(slic es, (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]

          -Miles

          Comment

          • Ivan Illarionov

            #6
            Re: slicing lists

            On Wed, 07 May 2008 21:13:27 -0400, Miles wrote:
            On Wed, May 7, 2008 at 7:46 PM, Ivan Illarionov
            <ivan.illariono v@gmail.comwrot e:
            On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
            >
            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]
            >
            IMHO this notation is confusing.
            >
            What's wrong with:
            [0]+x[2: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)
            So it should be x[0] + x[2:6] or x[0].extend(x[2:6])

            Comment

            • Ivan Illarionov

              #7
              Re: slicing lists

              On Thu, 08 May 2008 01:15:43 +0000, Ivan Illarionov wrote:
              On Wed, 07 May 2008 21:13:27 -0400, Miles wrote:
              >
              >On Wed, May 7, 2008 at 7:46 PM, Ivan Illarionov
              > <ivan.illariono v@gmail.comwrot e:
              > On Wed, 07 May 2008 23:29:27 +0000, Yves Dorfsman wrote:
              > >
              > 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]
              > >
              > IMHO this notation is confusing.
              > >
              > What's wrong with:
              > [0]+x[2: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)
              >
              So it should be x[0] + x[2:6] or x[0].extend(x[2:6])
              Oh, I meant
              [x[0]] + x[2:6]
              or
              y = [x[0]]
              y.extend(x[2:6])

              Sorry



              Comment

              • Yves Dorfsman

                #8
                Re: slicing lists

                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__(sel f, slices):
                if isinstance(slic es, (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').readli nes()
                r = [ e.strip().split (':') for e in p ]
                s = [ e[0:1] + e[2:] for e in r ]


                Or:

                p = file('/etc/passwd').readli nes()
                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.


                Yves.
                Calgary AIX Linux UNIX React TypeScript JavaScript python contractor consultant programmer Yves Dorfsman




                Comment

                • George Sakkis

                  #9
                  Re: slicing lists

                  On May 7, 11:34 pm, Yves Dorfsman <y...@zioup.com wrote:
                  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 ?
                  Given that it's a straightforward generalization of the existing
                  slicing syntax, it sure does make sense from a theoretical standpoint.
                  Whether it's a worthy addition is debatable though; I don't think
                  there are many common use cases to convince the core developers to
                  work on it. OTOH if you (or someone else) comes up with a working
                  patch, it might improve its chances of getting accepted.

                  George

                  Comment

                  • Boris Borcic

                    #10
                    Re: slicing lists

                    Yves Dorfsman wrote:
                    >
                    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 ?
                    >
                    Note that the s[0,2:6] syntax is currently allowed because of the distinct
                    semantics that the Numeric module and its successors numarray and numpy had for it.

                    Comment

                    • MRAB

                      #11
                      Re: slicing lists

                      On May 8, 4:34 am, Yves Dorfsman <y...@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__(sel f, slices):
                      if isinstance(slic es, (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').readli nes()
                      r = [ e.strip().split (':') for e in p ]
                      s = [ e[0:1] + e[2:] for e in r ]
                      >
                      Or:
                      >
                      p = file('/etc/passwd').readli nes()
                      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 ]

                      Comment

                      • Yves Dorfsman

                        #12
                        Re: slicing lists

                        MRAB wrote:
                        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 ]
                        Thanks, this is very elegant indeed, but because there are two list
                        comprehension expressions (the one defining r and the one defining s), it
                        means that the we're looping twice over the same list instead of once with
                        the e[0,2:] hypotetical notation ; or am I missing something ?

                        Yves.
                        Calgary AIX Linux UNIX React TypeScript JavaScript python contractor consultant programmer Yves Dorfsman

                        Comment

                        • Ian Kelly

                          #13
                          Re: slicing lists

                          On Wed, May 7, 2008 at 5:29 PM, Yves Dorfsman <yves@zioup.com wrote:
                          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]
                          >
                          I am surprised this notation is not supported, it seems intuitive.
                          A concrete example of the sort of thing I want to do:
                          >
                          p = file('/etc/passwd').readli nes()
                          q = [ e.strip().split (':')[0,2:] for e in p ]
                          >
                          (getting rid of the password / x field)
                          Have a look at the itemgetter function from the operator module.

                          g = itemgetter( 0, *range(2, 6) )
                          p = file("/etc/passwd").readli nes()
                          q = [ g( e.strip().split (':') ) for e in p ]

                          Comment

                          • castironpi@gmail.com

                            #14
                            Re: slicing lists

                            On May 9, 1:23 am, "Ian Kelly" <ian.g.ke...@gm ail.comwrote:
                            On Wed, May 7, 2008 at 5:29 PM, Yves Dorfsman <y...@zioup.com wrote:
                            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]
                            >
                            I am surprised this notation is not supported, it seems intuitive.
                            A concrete example of the sort of thing I want to do:
                            >
                            p = file('/etc/passwd').readli nes()
                            q = [ e.strip().split (':')[0,2:] for e in p ]
                            >
                            (getting rid of the password / x field)
                            >
                            Have a look at the itemgetter function from the operator module.
                            >
                            g = itemgetter( 0, *range(2, 6) )
                            p = file("/etc/passwd").readli nes()
                            q = [ g( e.strip().split (':') ) for e in p ]
                            The only thing is, is there is another natural meaning to [a,b:c].

                            Counting grids on the diagonals, the rational set is well defined:

                            0: 0, 0
                            1: 1, 0
                            2: 0, 1
                            3: 2, 0
                            4: 1, 1
                            5: 0, 2
                            6: 3, 0
                            7: 2, 1
                            ...

                            Thencefore ( 2, 0 ) : ( 3, 0 ) is well defined. Thencefore,

                            a,b:c,d

                            is not; x[a,b:c,d]= x[a]+ x[b:c]+ x[d].

                            Comment

                            • Yves Dorfsman

                              #15
                              Re: slicing lists

                              castironpi@gmai l.com wrote:
                              The only thing is, is there is another natural meaning to [a,b:c].
                              >
                              Counting grids on the diagonals, the rational set is well defined:
                              >
                              0: 0, 0
                              1: 1, 0
                              2: 0, 1
                              3: 2, 0
                              4: 1, 1
                              5: 0, 2
                              6: 3, 0
                              7: 2, 1
                              ...
                              >
                              Thencefore ( 2, 0 ) : ( 3, 0 ) is well defined. Thencefore,
                              >
                              a,b:c,d
                              >
                              is not; x[a,b:c,d]= x[a]+ x[b:c]+ x[d].
                              I'm not sure what you mean here. Could you give me a simple piece of code to
                              show an example ?


                              Yves.
                              Calgary AIX Linux UNIX React TypeScript JavaScript python contractor consultant programmer Yves Dorfsman

                              Comment

                              Working...