5 Best Ways to Add the Occurrence of Each Number as Sublists in Python

πŸ’‘ Problem Formulation: In Python, we often encounter the need to organize and count occurrences of items within a list. Specifically, for a list of numbers, the goal is to create a new list where each sublist contains a number from the original list followed by its count of occurrences. For example, given the input [1, 2, 2, 3, 3, 3], the desired output would be [[1, 1], [2, 2], [3, 3]].

Method 1: Using a Dictionary and List Comprehension

An efficient way to track occurrences is by utilizing a dictionary to count each element, followed by a list comprehension to pair each unique number with its count. This method is both concise and readable.

Here’s an example:

from collections import Counter

def count_occurrences(sequence):
    counts = dict(Counter(sequence))
    return [[num, count] for num, count in counts.items()]

print(count_occurrences([1, 2, 2, 3, 3, 3]))

Output:

[[1, 1], [2, 2], [3, 3]]

This code snippet first creates a dictionary that represents the count of each element using Counter from the collections module. It then creates a new list where each sublist has two elements: the number and its count.

Method 2: Iterative Counting with Sets

For a relatively straightforward, manual approach, you can iterate over a set of the numbers to count their occurrences in the original list, avoiding repeated counts for the same number.

Here’s an example:

def count_occurrences(sequence):
    unique_numbers = set(sequence)
    return [[num, sequence.count(num)] for num in unique_numbers]

print(count_occurrences([1, 2, 2, 3, 3, 3]))

Output:

[[1, 1], [2, 2], [3, 3]]

In this method, we first create a set from the list to identify all unique numbers. Then, for each number, we use the list.count() function to determine its frequency, creating a sublist with the number and its count.

Method 3: Using defaultdict

The defaultdict from the collections module can simplify the counting process, as it initializes dictionary values automatically helping to count occurrences without checking for keys.

Here’s an example:

from collections import defaultdict

def count_occurrences(sequence):
    counts = defaultdict(int)
    for num in sequence:
        counts[num] += 1
    return [[num, count] for num, count in counts.items()]

print(count_occurrences([1, 2, 2, 3, 3, 3]))

Output:

[[1, 1], [2, 2], [3, 3]]

By using defaultdict, this code snippet eliminates the need for key existence checks. For each number in the list, it increments the count associated with that number in the dictionary, then constructs the output list.

Method 4: Using groupby from itertools

Python’s itertools.groupby function can cluster identical elements in the list, which can then be converted into the desired format of sublists with counts.

Here’s an example:

from itertools import groupby

def count_occurrences(sequence):
    sequence.sort()
    grouped = groupby(sequence)
    return [[num, len(list(group))] for num, group in grouped]

print(count_occurrences([1, 2, 2, 3, 3, 3]))

Output:

[[1, 1], [2, 2], [3, 3]]

In this snippet, sequence.sort() is called to ensure that identical numbers are adjacent, complying with groupby‘s requirement. Then, for each group, we create a sublist with the number and the size of the group.

Bonus One-Liner Method 5: Using map and lambda

The combination of map() and lambda functions allow for a compact, though less readable, one-line solution for counting occurrences.

Here’s an example:

sequence = [1, 2, 2, 3, 3, 3]
print(list(map(lambda num: [num, sequence.count(num)], set(sequence))))

Output:

[[1, 1], [2, 2], [3, 3]]

In a single line, this method creates a set of the unique numbers and then maps each number to a sublist containing the number itself and the count of its occurrences in the original list.

Summary/Discussion

  • Method 1: Dictionary and List Comprehension. It is concise and leverages Python’s powerful Counter class. However, it involves importing an additional module.
  • Method 2: Iterative Counting with Sets. This approach is simple and doesn’t require any imports, but its performance could degrade with larger lists due to repeated calls to list.count().
  • Method 3: Using defaultdict. It simplifies the process by automatically handling key creation and can be more efficient than Method 2. However, it still involves importing a module.
  • Method 4: Using groupby from itertools. It is efficient for sorted lists and can be very readable but requires the input list to be sorted ahead of time, which may not be always desirable.
  • Method 5: Bonus One-Liner with map and lambda. It is a neat one-liner but can be less readable and not as performant when dealing with large datasets due to multiple calls to list.count().