-
How to remove or add items from a list
Posted by biggorilla on April 20, 2022 at 12:00 amHello,
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
-
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
-
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 usewhere 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
-
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
-
If Im following you, your two lists
L1
andL2
are the same length. You want a listA
of the same length in which itemA[i]
is the greater ofL1[i]
andL2[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.)
-
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.