KX Community

Find answers, ask questions, and connect with our KX Community around the world.
KX Community Guidelines

Home Forums kdb+ How to remove or add items from a list

  • How to remove or add items from a list

    Posted by biggorilla on April 20, 2022 at 12:00 am

    Hello,

    I know this is answered somewhere but I can’t find it! I have two lists and they’re slightly different lengths.

    How can I add or remove the first or last items in the lists?

    There are a few nulls at the start and end of each list and I think this is preventing me from doing some really incredible things with them.

    Please help, it’s urgent and I am sweating!

    Thanks

    biggorilla replied 9 months, 1 week ago 3 Members · 5 Replies
  • 5 Replies
  • mauricelim

    Member
    April 20, 2022 at 12:00 am

    You can use the drop (_) operator, where n is a number to drop.

    n_list

    To remove from the end of the list:

    -n_list neg[n]_list

    If you want to remove nulls, you can do something like:

    list except 0N

    You can use the drop with each (‘) operator to remove the same numbers of items from each list of different length, i.e.

    n_'(ls;ls2) -n_'(ls;ls2) neg[n]_'(ls;ls2)

    Or removing nulls from them

    (ls;ls2)except'0N

     

  • Laura

    Administrator
    April 20, 2022 at 12:00 am

    Because underscores can be part of names, separate a name from the Drop operator with spaces.

    q)n:3 q)n_ til 5 'n_ [0] n_ til 5 ^ q)n _ til 5 3 4 q)-2_ 3_ til 10 3 4 5 6 7

    The null keyword will find nulls. You can use where not null to remove all nulls. Or, to remove leading and trailing nulls, you can count and Drop the nulls from each end. Note below the use of the Zen monks idiom to return both the boolean and its reverse.  And commuting (switching the arguments of) Drop in order to use Over to apply it to a list of left arguments.

    q)q:0N 0N 3 4 0N 6 7 0N 8 0N
    q)q where not null q / lose all nulls 3 4 6 7 8 
    q)1 reversenot null q / Zen monks 0011011010b 0101101100b 
    q)?'[;1b]1 reversenot null q 2 1 
    q)q {y _ x}/1 -1*?'[;1b]1 reversenot null q / commuted Drop 3 4 0N 6 7 0N 8

     

    All neat tricks. But if you simply want to drop leading and trailing nulls, just trim them.

    q)trim q 3 4 0N 6 7 0N 8

     

  • biggorilla

    Member
    April 20, 2022 at 12:00 am

    Hello and the greatest of thanks to the both of you. Lots of useful info. Chin chin.

     

    I have warped headfirst into my next problem which is using these shiny new lists in a conditional.

    I want to compare these two lists, when one item of the same position of each list is greater than the other, I want to put it into a new list with some output. I am encountering a ‘mismatched type’ error despite both lists only containing floats.

    A:$[L1>L2;1;2]

    Here’s the structure I am using. Please help! My knees are weak.

    Thank you

     

  • Laura

    Administrator
    April 21, 2022 at 12:00 am

    If Im following you, your two lists L1 and L2 are the same length. You want a list A of the same length in which item A[i] is the greater of L1[i] and L2[i].

    The Greater operator  | is atomic, so iterates implicitly.

     

    q)show L1:10?10. 3.927524 5.170911 5.159796 4.066642 1.780839 3.017723 7.85033 5.347096 7.111716 4.11597 
    q)show L2:10?10. 4.931835 5.785203 0.8388858 1.959907 3.75638 6.137452 5.294808 6.916099 2.296615 6.919531 
    q)show A:L1|L2 / Greater 4.931835 5.785203 5.159796 4.066642 3.75638 6.137452 7.85033 6.916099 7.111716 6.919531

    A good deal of vector programming is just letting go of loops and tests. (Just takes practice.)

     

  • mauricelim

    Member
    April 21, 2022 at 12:00 am

    What you need is actually the (?) vector conditional operator: https://code.kx.com/q/ref/vector-conditional/

    ? accepts a boolean list as the first argument but $ accepts a boolean atom. Think of ? as a boolean mask.

Log in to reply.