Skip to main content

No project description provided

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.1.tar.gz (4.2 kB view details)

Uploaded Source

File details

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

File metadata

  • Download URL: rel2tree-6.0.1.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.1.tar.gz
Algorithm Hash digest
SHA256 aae0a62f45d5a7d096b9eb02d389d244331ed5196fff1f97e001bdddfb1c1896
MD5 cd0ee0e2f2b856546b74b5ee4c0fb15c
BLAKE2b-256 0db04f49bbebe941cde1e25d31dd38ff919805e16bdd249bd26a4900661391a8

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