Re: [personal kdb+] dictionary with flip

391 views
Skip to first unread message

Nick Psaris

unread,
Apr 27, 2021, 10:26:28 PM4/27/21
to personal...@googlegroups.com
as you point out, tables are stored in memory as a flipped dictionary of lists:

show t:flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
name       iq
--------------
Dent       98
Beeblebrox 42
Prefect    126

but you can treat a table as a list of dictionaries (and index them by row):

q)t 0
name| `Dent
iq  | 98

the resulting dictionary has atomic values and flipping it does not create a 'flipped dictionary of lists'.

q)flip t 0
'rank
  [0]  flip t 0

one option is to turn each of the dictionary values into a list before flipping it:
q)flip enlist each t 0
name iq
-------
Dent 98

another option is to generate a list of conforming dictionaries.  q will then coerce them back into a table.  in this example, the list only has one element (a dictionary), but it would work for many more (as long as they all have the same column names and the columns appear in the same order).

q)enlist t 0
name iq
-------
Dent 98

this is typically the desired behavior.  but if you actually wanted a list of dictionaries,  you are out of luck:

q)(t 0;t 0)
name iq
-------
Dent 98
Dent 98
q)t 0 0
name iq
-------
Dent 98
Dent 98



On Tue, Apr 27, 2021 at 12:49 PM srevu...@gmail.com <srevu...@gmail.com> wrote:
Hi All,
I am new to KDB+ and q.  I created the table with help of flip in below way.
Table creation
t:flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)

Then, I accessed the first record of table with index, like this way t[0].   seems it is returning dictionary.  But when I try to flip the returned results of t[0], it is throwing the rank error.

Can you please help me to understand.

Code:
q) t:flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
q) t[0]
name| `Dent
iq  | 98
q) type t[0]
99h
q) flip t[0]
'rank
  [0]  flip t[0]
       ^



--
You received this message because you are subscribed to the Google Groups "Kdb+ Personal Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to personal-kdbpl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/personal-kdbplus/d9ec4fa1-452a-4a72-9cae-2b40dd2f2e21n%40googlegroups.com.

András Dőtsch

unread,
May 3, 2021, 3:24:02 PM5/3/21
to personal...@googlegroups.com
To put it simple: flip needs an input that is at least two dimensional and rectangular.
So, a simple dict can't be flipped unless the values are lists of the same length or dicts of the same keys. In your case flip didn't work, because your dict was only one dimensional.

Some examples:
q) flip (1 2;3 4)
q) flip `x`y!(1 2;3 4)
q) flip (`a`b!1 2;`a`b!3 4)
q) flip `x`y! (`a`b!1 2;`a`b!3 4)

As a special case, flip also works if some of the values of the dict or list are atoms.
q) flip (1 2;3)
q) flip `a`b!(1 2;3)
q) ([]a:1 2;b:3)

The table syntax is equivalent to the flipped dict syntax:
q) parse[" flip `a`b!(1 2;3)"] ~ parse"([]a:1 2;b:3)"
1b

Regards,
András

Alexander Unterrainer

unread,
May 3, 2021, 3:24:10 PM5/3/21
to personal...@googlegroups.com
Hi,
I believe you a referencing to the example here: https://code.kx.com/q4m3/8_Tables/#81-table-definition

8.1.1 Review of Table as Column Dictionary

This says that a table is a flipped column dictionary. "When a dictionary’s value items are all same-length lists, it is a column dictionary." (As per definition here at the end of this page: https://code.kx.com/q/basics/dictsandtables/

when you select 1 row of a table, you no longer have a column dictionary, but a simple dictionary, which you can't flip. 

q)t:flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
q)t
name       iq
--------------
Dent       98
Beeblebrox 42
Prefect    126
q)t 0
name| `Dent
iq  | 98
q)

Now, it's worth mentioning (and actually important to remember), that a table is actually nothing else than a list of dictionaries. q is smart enough to use the keys of the dictionaries as column names (they obviously need to be the same). You can see this by trying the following:
q)(t 0;t 1)
name       iq
-------------
Dent       98
Beeblebrox 42

you get a table with two rows (the first two from the original table). Knowing this, you could get a 1 row table doing the following

q)enlist t 0
name iq
-------
Dent 98

One more thing about tables, we know that tables are flipped column dictionaries, but q actually doesn't flip (reorder the data) but only records that the data should be displayed as a table. You can see this by inspecting the table using 0N! 
q)0N!t
+`name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
name       iq
--------------
Dent       98
Beeblebrox 42
Prefect    126

The + in front of the dictionary is k-code for the flip function in q. 

q)flip
+:
(In order to keep things simple ignore the : in the above code snippet, it's k code and it's best to look at q code for now).

Hope this helps.

Alexander

srevu...@gmail.com

unread,
May 3, 2021, 3:24:14 PM5/3/21
to Kdb+ Personal Developers
Thanks Nick

srevu...@gmail.com

unread,
May 3, 2021, 4:04:45 PM5/3/21
to Kdb+ Personal Developers
Thanks Alexander
Reply all
Reply to author
Forward
0 new messages