How to sort a list of strings on a substring

Discussion in 'Python' started by Scott, Oct 5, 2009.

  1. Scott

    Scott Guest

    I create a list of logs called LogList. Here is a sample:

    LogList =
    ["inbound tcp office 192.168.0.125 inside 10.1.0.91 88",
    "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    "inbound udp office 192.168.0.220 inside 10.1.0.13 53"]

    I want to sort the list on index 3 of each string - the first IP
    Address.

    I only need strings with similar, first IP's to be together. I don't
    need all of the IP's to be in order. For example:
    either:
    SortedList =
    ["inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    -or-
    SortedList =
    ["inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    -or-
    etc.

    would be fine.

    I'm reading a lot on sort, sorted, cmp, etc. but I'm just not getting
    how to use an element of a string as a "key" within a list of strings.
    I'm using Python 2.6.2.

    Thanks
     
    Scott, Oct 5, 2009
    #1
    1. Advertising

  2. Scott

    n00m Guest

    Here you are:

    LogList = [\
    "inbound tcp office 192.168.0.125 inside 10.1.0.91 88",
    "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    "inbound udp office 192.168.0.220 inside 10.1.0.13 53"]


    LogList.sort(key=lambda x: x[x.index('1'):])

    for item in LogList:
    print item

    ===========================================================

    inbound udp lab 172.24.0.110 inside 10.1.0.6 161
    inbound tcp office 192.168.0.125 inside 10.1.0.91 88
    inbound udp office 192.168.0.220 inside 10.1.0.13 53
    inbound tcp office 192.168.0.220 inside 10.1.0.31 2967
     
    n00m, Oct 5, 2009
    #2
    1. Advertising

  3. Scott

    MRAB Guest

    Scott wrote:
    > I create a list of logs called LogList. Here is a sample:
    >
    > LogList =
    > ["inbound tcp office 192.168.0.125 inside 10.1.0.91 88",
    > "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > "inbound udp office 192.168.0.220 inside 10.1.0.13 53"]
    >
    > I want to sort the list on index 3 of each string - the first IP
    > Address.
    >
    > I only need strings with similar, first IP's to be together. I don't
    > need all of the IP's to be in order. For example:
    > either:
    > SortedList =
    > ["inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    > "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    > -or-
    > SortedList =
    > ["inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    > "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    > -or-
    > etc.
    >
    > would be fine.
    >
    > I'm reading a lot on sort, sorted, cmp, etc. but I'm just not getting
    > how to use an element of a string as a "key" within a list of strings.
    > I'm using Python 2.6.2.
    >

    Forget about cmp, just use the 'key' argument of the list's 'sort'
    method or the 'sorted' function (the latter is better if you want to
    keep the original list). The 'key' argument expects a function (anything
    callable, actually) that accepts a single argument (the item) and
    returns a value to be used as the key, and the items will be sorted
    according to that key. In this case you want the items sorted by the
    fourth 'word', so split the item into words and return the one at index
    3:

    def key_word(item):
    return item.split()[3]

    SortedList = sorted(LogList, key=key_word)

    If the function is short and simple enough, lambda is often used instead
    of a named function:

    SortedList = sorted(LogList, key=lambda item: item.split()[3])
     
    MRAB, Oct 6, 2009
    #3
  4. On Mon, 05 Oct 2009 15:45:58 -0700, n00m wrote:

    > Here you are:
    >
    > LogList = [\
    > "inbound tcp office 192.168.0.125 inside 10.1.0.91 88", "inbound tcp
    > office 192.168.0.220 inside 10.1.0.31 2967", "inbound udp lab
    > 172.24.0.110 inside 10.1.0.6 161", "inbound udp office 192.168.0.220
    > inside 10.1.0.13 53"]
    >
    >
    > LogList.sort(key=lambda x: x[x.index('1'):])



    No, that's incorrect. Try it with this data and you will see it fails:


    LogList = [
    "inbound tcp office1 192.168.0.125 inside 10.1.0.91 88",
    "inbound tcp office2 192.168.0.220 inside 10.1.0.31 2967",
    "inbound udp lab1 172.24.0.110 inside 10.1.0.6 161",
    "inbound udp office2 192.168.0.220 inside 10.1.0.13 53",
    "inbound udp lab2 172.24.0.121 inside 10.1.0.6 161",
    "inbound udp webby 220.96.0.2 inside 20.2.0.9 54",
    ]


    Worse, if you delete the last item ("webby"), the code silently does the
    wrong thing. Code that crashes is bad, but code that silently does the
    wrong thing is a nightmare. Your test succeeded by accident -- it was a
    fluke of the data that you failed to see both failure modes.

    The question asked was how to sort the list according to item 3 of the
    strings, *not* how to sort the list according to the first character '1'.
    The way to solve this correctly is by extracting item 3 and sorting on
    that, not by searching for the first character '1'. That is a hack[1]
    that just happened to work for the specific test data you tried it on.




    [1] Hack in the bad sense, not in the good sense.



    --
    Steven
     
    Steven D'Aprano, Oct 6, 2009
    #4
  5. Scott

    n00m Guest

    > No, that's incorrect. Try it with this data and you will see it fails:

    Of course, you are right, but I think the topic-starter is smart
    enough
    to understand that I suggested only a hint, a sketch, a sample of how
    to use "key=" with "lambda", not a ready-to-apply solution.
     
    n00m, Oct 6, 2009
    #5
  6. On Mon, 05 Oct 2009 20:33:51 -0700, n00m wrote:

    >> No, that's incorrect. Try it with this data and you will see it fails:

    >
    > Of course, you are right, but I think the topic-starter is smart enough
    > to understand that I suggested only a hint, a sketch, a sample of how to
    > use "key=" with "lambda", not a ready-to-apply solution.


    Oh please. That's a ridiculous excuse. Your post started with "Here you
    are" -- the implication is that you thought it *was* a solution, not a
    hint. A hint would be something like "Write a key function, perhaps using
    lambda, and pass it to the sort() method using the key parameter."

    There's no shame at writing buggy code. There's not a person here who has
    never made a silly mistake, and most of us have done so in public too.
    Some real clangers too. What matters is how folks respond to having the
    their mistakes pointed out, and whether they learn from it.




    --
    Steven
     
    Steven D'Aprano, Oct 6, 2009
    #6
  7. Scott

    n00m Guest

    English language is not my mother toung,
    so I can't grasp many subtle nuances of it.
    Maybe "here you are" means to me quite a
    different thing than to you.
     
    n00m, Oct 6, 2009
    #7
  8. Scott

    Scott Guest

    On Oct 5, 6:05 pm, MRAB <> wrote:
    > Scott wrote:
    > > I create a list of logs called LogList. Here is a sample:

    >
    > > LogList =
    > > ["inbound tcp office 192.168.0.125 inside 10.1.0.91 88",
    > > "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > > "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > > "inbound udp office 192.168.0.220 inside 10.1.0.13 53"]

    >
    > > I want to sort the list on index 3 of each string - the first IP
    > > Address.

    >
    > > I only need strings with similar, first IP's to be together. I don't
    > > need all of the IP's to be in order. For example:
    > > either:
    > > SortedList =
    > > ["inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > > "inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > > "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    > > "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    > > -or-
    > > SortedList =
    > > ["inbound tcp office 192.168.0.220 inside 10.1.0.31 2967",
    > > "inbound udp office 192.168.0.220 inside 10.1.0.13 53",
    > > "inbound udp lab 172.24.0.110 inside 10.1.0.6 161",
    > > "inbound tcp office 192.168.0.125 inside 10.1.0.91 88"]
    > > -or-
    > > etc.

    >
    > > would be fine.

    >
    > > I'm reading a lot on sort, sorted, cmp, etc. but I'm just not getting
    > > how to use an element of a string as a "key" within a list of strings.
    > > I'm using Python 2.6.2.

    >
    > Forget about cmp, just use the 'key' argument of the list's 'sort'
    > method or the 'sorted' function (the latter is better if you want to
    > keep the original list). The 'key' argument expects a function (anything
    > callable, actually) that accepts a single argument (the item) and
    > returns a value to be used as the key, and the items will be sorted
    > according to that key. In this case you want the items sorted by the
    > fourth 'word', so split the item into words and return the one at index
    > 3:
    >
    > def key_word(item):
    >      return item.split()[3]
    >
    > SortedList = sorted(LogList, key=key_word)
    >
    > If the function is short and simple enough, lambda is often used instead
    > of a named function:
    >
    > SortedList = sorted(LogList, key=lambda item: item.split()[3])


    Ok, the lambda worked as advertised. THANK YOU!!

    Thanks for giving both a def and lambda example. I'll be saving them.
    -Scott
     
    Scott, Oct 6, 2009
    #8
  9. Scott

    alex23 Guest

    Steven D'Aprano <> wrote:
    > Oh please. That's a ridiculous excuse. Your post started with "Here you
    > are" -- the implication is that you thought it *was* a solution, not a
    > hint. A hint would be something like "Write a key function, perhaps using
    > lambda, and pass it to the sort() method using the key parameter."


    In n00m's defense, the OP's question was "I'm just not getting how to
    use an element of a string as a "key" within a list of strings", which
    n00m's post did answer, and which did work with the data set given. If
    Scott had asked "could someone show me how to do this", then yes, the
    "here you are" would have been wrong.

    Ah, semantics and the lack of expression in text :)
     
    alex23, Oct 6, 2009
    #9
  10. On Mon, 05 Oct 2009 21:16:38 -0700, n00m wrote:

    > English language is not my mother toung, so I can't grasp many subtle
    > nuances of it. Maybe "here you are" means to me quite a different thing
    > than to you.


    It means "here is the thing you were looking for". Anyway, nothing I
    wrote was meant as an attack on you.


    --
    Steven
     
    Steven D'Aprano, Oct 6, 2009
    #10
  11. Scott

    n00m Guest

    In my early teen, school years "Let It Be" by The Beatles sounded for
    my
    ears (incredibly clearly and obviously!) as "Lia Ri Pip".
    In school I studied French, English only many years later.

    My inner translation of "Here you are!" is smth like
    "Catch it!", "Take it!", "Look at this!" etc
     
    n00m, Oct 6, 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. Klaus Neuner
    Replies:
    7
    Views:
    514
    Klaus Neuner
    Jul 26, 2004
  2. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    798
    Malcolm
    Jun 24, 2006
  3. Replies:
    7
    Views:
    764
    Stefan Arentz
    Sep 10, 2007
  4. Navin
    Replies:
    1
    Views:
    744
    Ken Schaefer
    Sep 9, 2003
  5. Replies:
    3
    Views:
    222
    Sherm Pendley
    Aug 3, 2005
Loading...

Share This Page