# Python – Sort by Frequency of second element in Tuple List

Given list of tuples, sort by frequency of second element of tuple.

Input : test_list = [(6, 5), (1, 7), (2, 5), (8, 7), (9, 8), (3, 7)]
Output : [(1, 7), (8, 7), (3, 7), (6, 5), (2, 5), (9, 8)]
Explanation : 7 occurs 3 times as 2nd element, hence all tuples with 7, are aligned first.

Input : test_list = [(1, 7), (8, 7), (9, 8), (3, 7)]
Output : [(1, 7), (8, 7), (3, 7), (9, 8)]
Explanation : 7 occurs 3 times as 2nd element, hence all tuples with 7, are aligned first.

Method #1 : Using sorted() + loop + defaultdict() + lambda

In this, we compute the frequency using defaultdict() and use this result to pass as param to lambda function to perform sorting using sorted() on basis of it.

## Python3

 `# Python3 code to demonstrate working of ``# Sort by Frequency of second element in Tuple List``# Using sorted() + loop + defaultdict() + lambda``from` `collections ``import` `defaultdict` `# initializing list``test_list ``=` `[(``6``, ``5``), (``2``, ``7``), (``2``, ``5``), (``8``, ``7``), (``9``, ``8``), (``3``, ``7``)]` `# printing original list``print``(``"The original list is : "` `+` `str``(test_list))` `# constructing mapping``freq_map ``=` `defaultdict(``int``)``for` `idx, val ``in` `test_list:``    ``freq_map[val] ``+``=` `1` `# performing sort of result ``res ``=` `sorted``(test_list, key ``=` `lambda` `ele: freq_map[ele[``1``]], reverse ``=` `True``)` `# printing results``print``(``"Sorted List of tuples : "` `+` `str``(res))`

Output
```The original list is : [(6, 5), (2, 7), (2, 5), (8, 7), (9, 8), (3, 7)]
Sorted List of tuples : [(2, 7), (8, 7), (3, 7), (6, 5), (2, 5), (9, 8)]```

Time Complexity: O(logn)
Auxiliary Space: O(n)

Method #2 : Using Counter() + lambda + sorted()

In this, the task of frequency computation is done using Counter(), rest all functionality is similar to above method.

## Python3

 `# Python3 code to demonstrate working of ``# Sort by Frequency of second element in Tuple List``# Using Counter() + lambda + sorted()``from` `collections ``import` `Counter` `# initializing list``test_list ``=` `[(``6``, ``5``), (``2``, ``7``), (``2``, ``5``), (``8``, ``7``), (``9``, ``8``), (``3``, ``7``)]` `# printing original list``print``(``"The original list is : "` `+` `str``(test_list))` `# constructing mapping using Counter``freq_map ``=` `Counter(val ``for` `key, val ``in` `test_list)` `# performing sort of result ``res ``=` `sorted``(test_list, key ``=` `lambda` `ele: freq_map[ele[``1``]], reverse ``=` `True``)` `# printing results``print``(``"Sorted List of tuples : "` `+` `str``(res))`

Output
```The original list is : [(6, 5), (2, 7), (2, 5), (8, 7), (9, 8), (3, 7)]
Sorted List of tuples : [(2, 7), (8, 7), (3, 7), (6, 5), (2, 5), (9, 8)]```

Time complexity: O(n log n), where n is the length of the input list test_list. The sorting operation takes O(n log n) time complexity, and constructing the frequency map using Counter() takes O(n) time complexity. Since O(n log n) is the dominant term.
Auxiliary Space: O(n), where n is the length of the input list test_list. This is because we are using a Counter() to construct a frequency map of the second element of each tuple in the input list, which takes O(n) auxiliary space. Additionally, we are storing the sorted list of tuples in memory, which also takes O(n) auxiliary space.

Method #3 : Using groupby() + sorted()

In this, the task of frequency computation is done by sorted() and groupby() functions from the itertools module.

Algorithm

```Sort the input list of tuples by the second element.
Count the frequency of each second element using a dictionary.
Sort the input list of tuples by the frequency of the corresponding second element, in reverse order.
Return the sorted list.```

## Python

 `from` `itertools ``import` `groupby  ``# import groupby function from itertools module` `def` `sort_by_frequency(test_list):  ``# define function called sort_by_frequency that takes a list called test_list as input``    ``freq_dict ``=` `{val: ``len``(``list``(group)) ``for` `val, group ``in` `groupby(``sorted``(test_list, key``=``lambda` `x: x[``1``]), ``lambda` `x: x[``1``])}  ``    ``# create a dictionary called freq_dict where each key is a unique second element of a tuple in test_list and its value is the number of times that second element appears in test_list``    ``# we do this by using the groupby function to group the tuples in test_list by their second element, then using len to count the number of tuples in each group``    ``# we use sorted to sort the list of tuples by their second element before using groupby, and we use a lambda function to specify that we want to group by the second element of each tuple``    ``# the resulting dictionary has keys that are unique second elements from test_list and values that are the frequency of each second element in test_list``    ``return` `sorted``(test_list, key``=``lambda` `x: freq_dict[x[``1``]], reverse``=``True``)  ``    ``# sort the original list of tuples (test_list) based on the values in freq_dict``    ``# we use a lambda function to specify that we want to sort by the value in freq_dict corresponding to the second element of each tuple in test_list``    ``# we sort the list in reverse order (highest frequency first)``    ` `test_list ``=` `[(``6``, ``5``), (``1``, ``7``), (``2``, ``5``), (``8``, ``7``), (``9``, ``8``), (``3``, ``7``)]  ``# define test_list``print``(``"The original list is : "` `+` `str``(test_list))  ``# print the original list``print``(``"The sorted list is : "` `+` `str``(sort_by_frequency(test_list)))  ``# print the sorted list returned by the sort_by_frequency function`

Output
```The original list is : [(6, 5), (1, 7), (2, 5), (8, 7), (9, 8), (3, 7)]
The sorted list is : [(1, 7), (8, 7), (3, 7), (6, 5), (2, 5), (9, 8)]```

Time complexity: O(n log n),where n is the length of test_list
Auxiliary Space: O(n),where n is the length of test_list

Method #4: Using numpy

• Convert the list of tuples into a numpy array.
• Use numpy’s argsort function to sort the array based on the frequency of the second element.
• Use numpy’s take function to get the sorted array based on the argsort indices.
• Convert the sorted array back to a list of tuples.

## Python3

 `import` `numpy as np` `# initializing list``test_list ``=` `[(``6``, ``5``), (``2``, ``7``), (``2``, ``5``), (``8``, ``7``), (``9``, ``8``), (``3``, ``7``)]` `# printing original list``print``(``"The original list is : "` `+` `str``(test_list))` `# convert the list to a numpy array``arr ``=` `np.array(test_list)` `# get the frequency of each second element using numpy's unique function``counts ``=` `np.unique(arr[:, ``1``], return_counts``=``True``)` `# sort the indices based on the frequency of the second element using numpy's argsort function``sorted_indices ``=` `np.argsort(``-``counts[``1``])` `# create an empty array to store the sorted tuples``sorted_arr ``=` `np.empty_like(arr)` `# iterate over the sorted indices and fill in the sorted array``start ``=` `0``for` `i ``in` `sorted_indices:``    ``freq ``=` `counts[``1``][i]``    ``indices ``=` `np.where(arr[:, ``1``] ``=``=` `counts[``0``][i])[``0``]``    ``end ``=` `start ``+` `freq``    ``sorted_arr[start:end] ``=` `arr[indices]``    ``start ``=` `end` `# convert the sorted array back to a list of tuples``res ``=` `[``tuple``(row) ``for` `row ``in` `sorted_arr]` `# printing results``print``(``"Sorted List of tuples : "` `+` `str``(res))`

Output:

``` The original list is : [(6, 5), (2, 7), (2, 5), (8, 7), (9, 8), (3, 7)]
Sorted List of tuples : [(2, 7), (8, 7), (3, 7), (6, 5), (2, 5), (9, 8)]```

Time complexity: O(n log n) (due to sorting)
Auxiliary space: O(n) (due to creating a numpy array)

Previous
Next