Question: I have a dictionary,

```
myDict = {1: 10, 1.1: 10, 2: 15, 2.1: 20}

```

but instead of only 4 key-value pairs, it has thousands of them and some are very close together like the key `1` and the key `1.1` in my example sometimes up to machine epsilon. 

Is there a simple procedure how I can bin the keys together while adding up their corresponding values? In my example with binwidth 1 this would become

```
myBinnedDict = {1.05: 20, 2.05: 35}

```

where I chose the keys as the averages of the previous keys (could maybe even be weighted with the value of the corresponding key, but since this is application specific, it's not so important here.)

Thanks for the help.

P.S.: I'm aware that I ended up here because I probably did not use the data structure competently.

Answer: 
You can use `itertools.groupby` with some one-line comprehensions:

```
from itertools import groupby
from statistics import mean

myDict = {1: 10, 1.1: 10, 2: 15, 2.1: 20}

{mean(keys): sum(vals) for keys, vals in (zip(*g) for _, g in groupby(sorted(myDict.items()), key=lambda x: round(x[0])))}

```

Anything that rounds to the same whole number will be grouped together.

Explanation:

```
{
    mean(keys): sum(vals)
    for keys, vals in (
        zip(*g) for _, g in groupby(
            sorted(myDict.items()), 
            key=lambda x: round(x[0])
        )
    )
}

```

`sorted(myDict.items())` sorts the dictionary by key (it sorts lexicographically, and the key comes first).

`groupby(sorted(myDict.items()), key=lambda x: round(x[0])))}` groups the sorted items by the value of the rounded key.

`zip(*g) for _, g in groupby(...)` tranposes the groups spat out by `groupby`. `groupby` yields two things: the "key" (the rounded number) which we don't need (denoted by `_`) and the "group", which is of the format `(key, val), (key, val), (key, val), etc.` The `zip(*)` transforms this into `(key, key, key, ...), (val, val, val, ...)`, which is what we need.

Finally, `mean(keys): sum(vals) for keys, vals in (...)` transforms the keys and values by applying `mean` and `sum`, respectively.
We can use some `numpy` to take advantage of some array operations.

```
import numpy as np

myDict = {1: 10, 1.1: 10, 1.7: 6, 2: 15, 2.1: 20, 2.3: 50, 2.6: 1, 3: 1}

x = np.array([*myDict]) # just the keys from the dictionary

print(x)

array([1. , 1.1, 1.7, 2. , 2.1, 2.3, 2.6, 3. ])

clusters = x[x == x.astype(int)] # just the integers to get the bins

print(clusters)

array([1., 2., 3.])

digits = np.digitize(x, clusters) # bin the data based on the bins

print(digits)

array([1, 1, 1, 2, 2, 2, 2, 3])

res = dict()

for c in clusters:
    keys = x[digits == c] # grab all keys for this bin
    value = sum([myDict.get(k) for k in keys]) # sum values for these keys from the original dict
    res[keys.mean().round(2)] = value

print(res)

{1.27: 26, 2.25: 86, 3.0: 1}

```