Skip to main content

Convert a list of records to a JSON-like structure

Project description

rel2tree

Convert a list of records to a JSON-like structure.

Tutorial

Let's suppose you have a set of data:

[
  {"name": "Jane", "city": "New York", "sales": 23},
  {"name": "Joe", "city": "New York", "sales": 11},
  {"name": "Jane", "city": "Chicago", "sales": 21},
  {"name": "Jane", "city": "New York", "sales": 4},
  {"name": "Joe", "city": "New York", "sales": 13},
  {"name": "Joe", "city": "Chicago", "sales": 31},
  {"name": "Jane", "city": "New York", "sales": 7},
]

You may want a nice summary, something like this:

[
  {
    "name": "Jane",
    "cities": [
      {
        "city": "New York",
        "sales": 34
      },
      {
        "city": "Chicago",
        "sales": 21
      }
    ],
    "sum": 55
  },
  {
    "name": "Joe",
    "cities": [
      {
        "city": "New York",
        "sales": 24
      },
      {
        "city": "Chicago",
        "sales": 31
      }
    ],
    "sum": 55
  }
]

This can be done relatively easily by iterating over the data set and building the final structure. This code is far from declarative (looking at the code itself you can not easily say the final data structure) and if the structure of the data gets more complex, or your requirements changes, your code can blow up fast.

Let's see how you do it with rel2tree:

f = F().groupby(lambda x: x["name"], F().dict({
    "name": groupkey(),
    "cities": F().groupby(lambda x: x["city"], F().dict({
        "city": groupkey(),
        "sales": F().map(lambda x: x["sales"]).t(sum)
    })),
    "sum": F().map(lambda x: x["sales"]).t(sum)
}))

result = f(data)

The code above can be tricky for the first sight, but definitively much more declarative.

map, filter, sort

The most basic usage of rel2tree is mapping a list. Say we have a list and want to duplicate of its elements.

data = [1, 2, 3, 4]
result = list(map(lambda x: 2 * x, data))

With rel2tree it looks like this:

data = [1, 2, 3, 4]
f = F().map(lambda x: 2 * x)
result = f(data)

Note that in the above example f can be thought of as a recipe. It can be reused with a different set of data any time.

Now we can further modify our list by mapping again. Say we want to add 5 to each elements:

f2 = f.map(lambda x: x + 5)
result = f2(data)
result = [7, 9, 11, 13]

To filter our list, we need a function that returns True for elements to keep in the list.

f3 = f2.filter(lambda x: x < 10)
result = f3(data)
result = [7, 9]

Sorting works the same as python's sorted function:

f4 = f3.sort(lambda x: -x)
result = f4(data)
result = [9, 7]

dict

The usage of dict is easiest to describe with an example:

data = [1, 2, 3, 4]
f = F().dict({
    "list": F(),
    "even": F().filter(lambda x: x % 2 == 0),
    "odd": F().filter(lambda x: x % 2 != 0),
})
result = f(data)

Here is the result:

{
  "list": [1, 2, 3, 4],
  "even": [2, 4],
  "odd": [1, 3]
}

For each key in the dictionary we specify an F expression. The full list will be processed by each of these F-s and the result will be a single dictionary.

groupby

groupby needs a function as its first argument. This function will be called with each items in the list to calculate a group key. Items with the same group keys are collected in lists. The result will be a list of these groups.

data = range(10)
f = F().groupby(lambda x: x % 2)
print(json.dumps(f(data)))
[[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]]

An F can be given to groupby as the second argument. In this case each list will be given to this F. To continue our example above, we may calculate the sum of even and odd numbers:

data = range(10)
f = F().groupby(lambda x: x % 2, F().t(sum))
print(json.dumps(f(data)))
# [20, 25]

This last example shows how to apply an arbitrary function on the whole list: f.t(func). In this case we get func(lst) as a result. t means f.t(func) does not return an F expression but an instance of class T. The difference is that you can not further chain T-s, they are 'terminating' the chain. Most F methods assume they will be used with lists. If you know your function will return a list which you may want to further manipulate by chaining, you can use f.f(func).

const and groupkey

TODO

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rel2tree-6.0.2.tar.gz (4.2 kB view details)

Uploaded Source

File details

Details for the file rel2tree-6.0.2.tar.gz.

File metadata

  • Download URL: rel2tree-6.0.2.tar.gz
  • Upload date:
  • Size: 4.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.6.8

File hashes

Hashes for rel2tree-6.0.2.tar.gz
Algorithm Hash digest
SHA256 0c7d986f0242125033da9fc29789d647f3362a8f3146f135f1777f7c50e5b034
MD5 33d323e521d2a6438ad99db96e0797c9
BLAKE2b-256 7b65637b4f83d439ba5547d710fb78702980ae3dffb7abfc5bb1c686766fdbc6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page