cancel
Showing results for 
Search instead for 
Did you mean: 

How to remove or add items from a list

BigGorilla
New Contributor III

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

2 ACCEPTED SOLUTIONS

mauricelim
New Contributor II

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

 

View solution in original post

SJT
Contributor III
Contributor III

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 reverse\not null q  / Zen monks
0011011010b
0101101100b
q)?'[;1b]1 reverse\not null q
2 1
q)q {y _ x}/1 -1*?'[;1b]1 reverse\not 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

 

View solution in original post

5 REPLIES 5

mauricelim
New Contributor II

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

 

SJT
Contributor III
Contributor III

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 reverse\not null q  / Zen monks
0011011010b
0101101100b
q)?'[;1b]1 reverse\not null q
2 1
q)q {y _ x}/1 -1*?'[;1b]1 reverse\not 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
New Contributor III

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

 

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.

SJT
Contributor III
Contributor III

If I’m 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.)