HOWTO · Python
如何在 Python 列表中计算唯一值
计算 Python 列表中的唯一值
本页内容
统计 Python 列表中唯一值的一种简单方法是 len(set(values)),只要列表中的元素都可哈希即可使用,例如数字、字符串,以及元素全部可哈希的元组。如果还需要知道每个值出现了多少次,collections.Counter 可以在一次遍历中给出不同值的数量及各值的出现频率;如果数据已经存储在 NumPy 数组中,numpy.unique 则很合适。本文将介绍这三种方法,并说明如何选择。
使用 set() 统计唯一值
内置的 set() 函数会将列表转换为集合,而集合中的每个不同值只保留一次。将结果传给 len(),无需额外导入即可得到唯一值的数量。
运行以下示例。示例中的代码和显示的标签或输出保留英文:
本节中的代码以及显示的标签或输出仍为英文。
values = [1, 2, 2, 3, 4, 4, 5]
unique_values = set(values)
print(len(unique_values))
输出:
本示例显示的代码和输出保留英文。
5
set(values) 会去掉重复的 2 和 4,随后 len() 会报告剩余元素的数量。输入元素必须可哈希;如果列表包含其他列表或字典等元素,Python 会报告 TypeError。还要注意,集合不会保留列表的原始顺序,因此它能回答“有多少个”,却不能说明“哪个先出现”。如果需要按首次出现的顺序获取唯一值,可以改用 list(dict.fromkeys(values));它的长度仍是不同值的数量。
使用 collections.Counter 统计唯一值
collections.Counter 是一种类似字典的类,用于统计可迭代对象中每个元素出现的次数。如果想同时得到不同值的数量和每个值的出现频率,它就是合适的工具。
示例中的代码和显示的标签或输出保留英文。
本节中的代码以及显示的标签或输出仍为英文。
from collections import Counter
values = ["apple", "banana", "apple", "orange", "banana", "kiwi"]
counter = Counter(values)
print(len(counter))
print(dict(counter))
输出:
本示例显示的代码和输出保留英文。
4
{'apple': 2, 'banana': 2, 'orange': 1, 'kiwi': 1}
counter 会将每个值映射到它出现的次数,因此 len(counter) 统计的是不同键的数量——在这个列表中是四个。对计数器进行索引,例如 counter["apple"],可以得到某个值的出现次数;counter.most_common(1) 会返回出现次数最多的元素。与 set() 一样,collections.Counter 适用于可哈希元素,并且属于标准库。
使用 NumPy 统计唯一值
NumPy 是一个第三方软件包,可通过 pip install numpy 安装。它的 numpy.unique 函数会返回类数组输入中排序后的唯一值。结果的大小就是不同值的数量;传入 return_counts=True,还可以同时得到每个值出现的次数。
运行以下示例。示例中的代码和显示的标签或输出保留英文:
本节中的代码以及显示的标签或输出仍为英文。
import numpy as np
values = np.array([1, 2, 2, 3, 4, 4, 5])
unique_values, counts = np.unique(values, return_counts=True)
print(len(unique_values))
for value, count in zip(unique_values, counts):
print(value, count)
输出:
本示例显示的代码和输出保留英文。
5
1 1
2 2
3 1
4 2
5 1
这里,unique_values 按排序顺序保存五个不同的数字,counts 则记录每个数字出现的次数——2 和 4 各出现两次。由于 numpy.unique 会对结果排序,因此它也适合需要按顺序获取不同值的任务。如果数据已经存放在 NumPy 数组中,或项目已经依赖 NumPy,可以使用这种方法;对于普通 Python 列表,set() 方法无需增加额外依赖。
选择合适的方法
这三种方法得到的不同值数量相同,因此应根据输入数据以及你还需要哪些信息来选择:
- 如果只需要统计不同的可哈希元素,并希望使用最简短且仅依赖标准库的方案,请使用
set()。 - 如果还需要每个值的出现频率、出现次数最多的元素,或其他逐值统计结果,请使用
collections.Counter。 - 如果数据已经是 NumPy 数组,或需要排序后的唯一值,请使用
numpy.unique;若还需要各值的频率,可传入return_counts=True。
无论选择哪种方法,关键都在于你还需要哪些额外信息:各值的频率、排序后的结果,还是避免增加额外依赖。至于不同值的数量,这三种方法都能以相同的方式给出结果。