The code you read here implements grouping lists using grouping functions and counting the number of elements in each group.

The code snippet read here is from 30-seconds-of-Python.

count_by1

def count_by(arr, fn=lambda x: x) :
  key = {}
  for el in map(fn, arr):
    key[el] = 1 if el not in key else key[el] + 1
  return key

# EXAMPLES
from math import floor
count_by([6.1.4.2.6.3], floor) # {6: 2, 4: 1}
count_by(['one'.'two'.'three'].len) # {3: 2, 5: 1}
Copy the code

Count_by groups the elements in a list according to a given function and returns the number of elements in each group. This uses map() to map the values of the given list using the given function. Iterate over the map, increasing the number of elements with each occurrence.

This function uses not in to determine whether the dictionary currently contains the specified key. If it does not, it adds the key to the dictionary and sets the corresponding value to 1. If so, add value by 1.

Use dictionary derivation

The dictionary derivation is used in ** Python code reading: Group the elements in a list according to a given function ** to group the list. You can use the same approach here and get the length of the list directly after grouping. But this way of writing it is going through the list twice, which makes it less efficient.

def count_by(lst, fn) :
  return {key : len([el for el in lst if fn(el) == key]) for key in map(fn, lst)}
Copy the code

usecollections.defaultdictSimplify the code

class collections.defaultdict([default_factory[, ...]])
Copy the code

Defaultdict contains a default_factory property that can be used to quickly construct dictionaries of a specified style.

When using int as default_factory, you can use defaultdict for counting. So you can use it directly to simplify your code. Compared to the dictionary derivation method, you only need to loop through the list once.

 from collections import defaultdict

def count_by(lst, fn) :
  d = defaultdict(int)
  for el in lst:
    d[fn(el)] += 1
  return d
Copy the code

When you use list as the default_factory, you easily convert a sequence (of key-value pairs) into a dictionary (of key-lists). So we can rewrite the Python code to read: group the elements in a list according to a given function ** to improve efficiency.

def group_by(lst, fn) :
  d = defaultdict(list)
  for el in lst:
    d[fn(el)].append(el)
  return d

# EXAMPLES
from math import floor
group_by([6.1.4.2.6.3], floor) # {4: [4.2], 6: [6.1, 6.3]}
group_by(['one'.'two'.'three'].len) # {3: ['one', 'two'], 5: ['three']}
Copy the code

  1. The code snippet read in this article is from 30-seconds of Python. ↩