Is there a better way to chose a slice of a list?

Discussion in 'Python' started by walterbyrd, May 8, 2009.

  1. walterbyrd

    walterbyrd Guest

    This works, but it seems like there should be a better way.

    --------------
    week = ['sun','mon','tue','wed','thu','fri','sat']
    for day in week[week.index('tue'):week.index('fri')]:
    print day
    ---------------
     
    walterbyrd, May 8, 2009
    #1
    1. Advertising

  2. walterbyrd

    Guest

    On May 8, 3:03 pm, walterbyrd <> wrote:
    > This works, but it seems like there should be a better way.
    >
    > --------------
    > week = ['sun','mon','tue','wed','thu','fri','sat']
    > for day in week[week.index('tue'):week.index('fri')]:
    >    print day
    > ---------------


    Depending on the context this style might help:

    >>> week = ['sun','mon','tue','wed','thu','fri','sat']
    >>> tue_fri = slice(week.index('tue'), week.index('fri'))
    >>> for day in week[tue_fri]:

    print day

    But I don't really see it as an improvement unless you are using those
    intervals repeatedly.
     
    , May 8, 2009
    #2
    1. Advertising

  3. walterbyrd

    John Yeung Guest

    On May 8, 3:03 pm, walterbyrd <> wrote:
    > This works, but it seems like there should be a better way.
    >
    > --------------
    > week = ['sun','mon','tue','wed','thu','fri','sat']
    > for day in week[week.index('tue'):week.index('fri')]:
    >    print day
    > ---------------


    I think you should provide much more information, primarily why you
    want to do this. What is the larger goal you are trying to achieve?

    In the absence of further information, it seems to me that you are
    trying to create an enumerated type. For various ideas to achieve
    this simply, depending on your purpose, see

    http://norvig.com/python-iaq.html

    If you want a more thorough treatment, maybe try this package:

    http://pypi.python.org/pypi/enum/

    There may be other recipes and packages; you can Google for them using
    keywords "python enum" or similar.

    John
     
    John Yeung, May 9, 2009
    #3
  4. walterbyrd

    walterbyrd Guest

    On May 8, 5:55 pm, John Yeung <> wrote:
    > On May 8, 3:03 pm,walterbyrd<> wrote:
    >
    > > This works, but it seems like there should be a better way.

    >
    > > --------------
    > > week = ['sun','mon','tue','wed','thu','fri','sat']
    > > for day in week[week.index('tue'):week.index('fri')]:
    > >    print day
    > > ---------------

    >
    > I think you should provide much more information, primarily why you
    > want to do this.  What is the larger goal you are trying to achieve?


    I am just looking for a less verbose, more elegant, way to print a
    slice of a list. What is hard to understand about that? I am not sure
    how enumerated types help.
     
    walterbyrd, May 19, 2009
    #4
  5. walterbyrd

    Terry Reedy Guest

    walterbyrd wrote:
    > On May 8, 5:55 pm, John Yeung <> wrote:
    >> On May 8, 3:03 pm,walterbyrd<> wrote:
    >>
    >>> This works, but it seems like there should be a better way.
    >>> --------------
    >>> week = ['sun','mon','tue','wed','thu','fri','sat']
    >>> for day in week[week.index('tue'):week.index('fri')]:
    >>> print day
    >>> ---------------

    >> I think you should provide much more information, primarily why you
    >> want to do this. What is the larger goal you are trying to achieve?

    >
    > I am just looking for a less verbose, more elegant, way to print a
    > slice of a list.


    week[2:5] # ;-)

    If you want the interpreter to turn non-ints into ints for you, you will
    have to give it some sort of function or mapping to use.

    dayint = {day:i for i,day in enumeratr(week)} # works in Py3 at least
    week[dayint['tue']:dayint['fri']]

    # or, untested, basing attrodic on memory of posted code

    class attrodic(): #py3
    def __init__(self, dic):
    self.__dict__.update(dic)

    di = attrodic(week)
    week[di.tue:di.fri]

    Most elegant, and most setup work ;-).

    Terry Jan Reedy
     
    Terry Reedy, May 20, 2009
    #5
  6. walterbyrd

    Rhodri James Guest

    On Tue, 19 May 2009 22:38:19 +0100, walterbyrd <>
    wrote:

    > On May 8, 5:55 pm, John Yeung <> wrote:
    >> On May 8, 3:03 pm,walterbyrd<> wrote:
    >>
    >> > This works, but it seems like there should be a better way.

    >>
    >> > --------------
    >> > week = ['sun','mon','tue','wed','thu','fri','sat']
    >> > for day in week[week.index('tue'):week.index('fri')]:
    >> >    print day
    >> > ---------------

    >>
    >> I think you should provide much more information, primarily why you
    >> want to do this.  What is the larger goal you are trying to achieve?

    >
    > I am just looking for a less verbose, more elegant, way to print a
    > slice of a list. What is hard to understand about that? I am not sure
    > how enumerated types help.


    This is verbose and inelegant because of the way you're storing and
    using the data, hence (I presume) John's question. The more elegant
    approach is not to try to index a list with strings, but to keep you
    "day" data in numeric form and use that to slice with, and for that
    enums will greatly help you keep things clear. However, whether that's
    worth doing or not depends on the bigger picture, and you haven't
    told us anything that would help us figure that out.

    --
    Rhodri James *-* Wildebeeste Herder to the Masses
     
    Rhodri James, May 20, 2009
    #6
  7. walterbyrd

    John Machin Guest

    On May 20, 7:38 am, walterbyrd <> wrote:
    > On May 8, 5:55 pm, John Yeung <> wrote:
    >
    > > On May 8, 3:03 pm,walterbyrd<> wrote:

    >
    > > > This works, but it seems like there should be a better way.

    >
    > > > --------------
    > > > ---------------

    >
    > > I think you should provide much more information, primarily why you
    > > want to do this.  What is the larger goal you are trying to achieve?

    >
    > I am just looking for a less verbose, more elegant, way to print a
    > slice of a list. What is hard to understand about that?


    Ummm two things, (1) You didn't say that was what you wanted (2) It's
    a nonsense anyway:

    Your original statement "choose a slice of alist": answer = alist
    [lo:hi]

    Your current statement "print a slice of a list" (one element per line
    as per your example): can not be done much less verbosely and more
    elegantly than:
    for x in alist[lo:hi]:
    print x

    Your real problem appears to be the horrid method of deriving lo and
    hi.

    You gave ONE example without stating anything more precise than that
    it was an example of a slice of a list [which was obvious anyway] and
    didn't specify in what sense of "better" you wanted a better way. So
    people have to guess what you really want.

    Guessing that the 'tue' and 'fri' in your one example will always be
    constants, here are two options:

    E.g. given
    week = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']

    Option (1):
    SUN, MON, TUE, WED, THU, FRI, SAT = range(7)
    for day in week[TUE:FRI]:
    print day

    Option (2):
    for day in week[2:5]:
    print day

    HTH,
    John
     
    John Machin, May 20, 2009
    #7
  8. On Tue, 19 May 2009 14:38:19 -0700, walterbyrd wrote:

    > On May 8, 5:55 pm, John Yeung <> wrote:
    >> On May 8, 3:03 pm,walterbyrd<> wrote:
    >>
    >> > This works, but it seems like there should be a better way.

    >>
    >> > --------------
    >> > week = ['sun','mon','tue','wed','thu','fri','sat'] for day in
    >> > week[week.index('tue'):week.index('fri')]:
    >> >    print day
    >> > ---------------

    >>
    >> I think you should provide much more information, primarily why you
    >> want to do this.  What is the larger goal you are trying to achieve?

    >
    > I am just looking for a less verbose, more elegant, way to print a slice
    > of a list. What is hard to understand about that? I am not sure how
    > enumerated types help.


    Printing a slice of a list is about as concise and elegant as possible:

    print alist[slice_obj]

    or

    print alist[start:end:step]

    But that's not what the example in your first post suggests. Your example
    suggests you have *two* problems:

    (1) Given a slice, how to print each item in the slice _individually_.

    The answer to that is

    for x in aslice:
    print x

    Pretty concise and elegant.



    (2) Given an arbitrary starting and ending _item_ rather than _position_,
    how to concisely and elegantly generate a slice.

    There are many answers, depending on _why_ you want to do this. One
    possible answer is to write a function to do it:

    def print_slice(alist, start_item, end_item):
    start_pos = alist.index(start_item)
    end_pos = alist.index(end_item)
    for x in alist[start_pos:end_pos]:
    print x

    Now print_slice(week, 'tue', 'fri') is pretty concise and elegant.

    Another answer is: Don't do that, do something else. If you have an
    enumerated type, then you could (in principle) do this:

    week = enumerated('mon tue wed thu fri sat sun')
    for x in week.tue-week.fri:
    print x


    depending on the enumerated type itself naturally.



    --
    Steven
     
    Steven D'Aprano, May 20, 2009
    #8
  9. >>>>> walterbyrd <> (w) wrote:

    >w> On May 8, 5:55 pm, John Yeung <> wrote:
    >>> On May 8, 3:03 pm,walterbyrd<> wrote:
    >>>
    >>> > This works, but it seems like there should be a better way.
    >>>
    >>> > --------------
    >>> > week = ['sun','mon','tue','wed','thu','fri','sat']
    >>> > for day in week[week.index('tue'):week.index('fri')]:
    >>> >    print day
    >>> > ---------------
    >>>
    >>> I think you should provide much more information, primarily why you
    >>> want to do this.  What is the larger goal you are trying to achieve?


    >w> I am just looking for a less verbose, more elegant, way to print a
    >w> slice of a list. What is hard to understand about that? I am not sure
    >w> how enumerated types help.


    You didn't say that in the OP.

    But you can extend the list type to accept slices with strings in them.
    The language spec says they should be ints but apparently this is not
    enforced. Of course this makes it vulnerable for future misbehaviour.

    class KeyList(list):
    def __getitem__(self, indx):
    if isinstance(indx, slice):
    start = indx.start
    stop = indx.stop
    # add support for step if you want
    if not isinstance(start, int):
    start = self.index(start)
    if not isinstance(stop, int):
    stop = self.index(stop)
    return list.__getitem__(self, slice(start,stop))
    return list.__getitem__(self, indx)

    week = KeyList(['sun','mon','tue','wed','thu','fri','sat'])
    for day in week['tue':'fri']:
    print day

    tue
    wed
    thu

    Note that 'fri' is not included according to standard Python conventions
    about the end of a slice. Change the code if you are not happy with it
    and you don't mind getting inconsistent semantics.
    --
    Piet van Oostrum <>
    URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
    Private email:
     
    Piet van Oostrum, May 20, 2009
    #9
  10. walterbyrd

    walterbyrd Guest

    On May 19, 5:31 pm, Ben Finney <> wrote:

    > That's just the same micro-goal re-stated. What is your larger problem
    > of which this is a part? Perhaps a better approach can be suggested when
    > that context is known.


    I am processing a huge spreadsheet which I have converted to a csv
    format. Each row will be a wiki page with several sub-headings. The
    spreadsheet contains information about servers. Wiki sub-headings may
    include: 'hardware', 'software', 'users', 'network swith settings'.
    'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and
    so on. So the first six columns in the spreadsheet may go under
    'hardware' the next six under 'software' and so on.

    I have already created the wiki pages, using a method similar to what
    I first posted. But, it seems like there should be a better way to to
    do it. So, for future reference, I was just wondering.
     
    walterbyrd, May 20, 2009
    #10
  11. walterbyrd

    Rhodri James Guest

    On Wed, 20 May 2009 17:08:08 +0100, walterbyrd <>
    wrote:

    > I am processing a huge spreadsheet which I have converted to a csv
    > format. Each row will be a wiki page with several sub-headings. The
    > spreadsheet contains information about servers. Wiki sub-headings may
    > include: 'hardware', 'software', 'users', 'network swith settings'.
    > 'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and
    > so on. So the first six columns in the spreadsheet may go under
    > 'hardware' the next six under 'software' and so on.
    >
    > I have already created the wiki pages, using a method similar to what
    > I first posted. But, it seems like there should be a better way to to
    > do it. So, for future reference, I was just wondering.


    Given that you're already making presumptions about the nature of your
    data, named constants or enums are the most concise thing to use together
    with a quick check of the column header row to make sure that the
    constants really do refer to the right columns.

    If you want something a little more bullet-proof, create a dictionary
    mapping the column headers (as read in) to column numbers and use that
    to generate the slice limits. Since that still relies on the column
    headers being what you expect them to be, and at least partially in the
    order you expect them to be, it's probably not enough of a win to bother
    with.

    Trying to slice a list by value is never going to look pretty because
    lists aren't designed to be indexed by value. Worse, if you were
    doing this a lot (as you imply) then it's going to be horribly
    inefficient, since you're doing an extra two (or more) O(n) searches
    for every row.

    --
    Rhodri James *-* Wildebeeste Herder to the Masses
     
    Rhodri James, May 22, 2009
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Francois

    Why I chose Python over Ruby

    Francois, Mar 5, 2006, in forum: Python
    Replies:
    22
    Views:
    887
    Torsten Bronger
    Mar 6, 2006
  2. Chose file upload location

    , Jul 5, 2007, in forum: ASP .Net
    Replies:
    8
    Views:
    436
    Jon Paal [MSMD]
    Jul 6, 2007
  3. Paul Rubin
    Replies:
    5
    Views:
    440
    Hendrik van Rooyen
    Aug 6, 2009
  4. max
    Replies:
    0
    Views:
    100
  5. Smugsboy

    How to dynamically chose download file

    Smugsboy, Dec 22, 2005, in forum: Javascript
    Replies:
    6
    Views:
    109
    Thomas 'PointedEars' Lahn
    Dec 23, 2005
Loading...

Share This Page