Python移除列表中每个元素的N次出现:求更优/一行代码方案
更优实现与一行代码写法
原代码的问题
- 每次调用
numbers.count(i)都会完整遍历一次列表,时间复杂度为O(m*k)(m是列表长度,k是不同元素数量),数据量大时效率低下 - 使用
set(numbers)遍历会打乱原列表中元素的出现顺序
高效实现
保持原元素顺序
如果需要保留原列表中元素的相对顺序,推荐用collections.Counter统计次数后遍历原列表,仅需两次遍历,时间复杂度O(m):
from collections import Counter numbers = [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3] n = 2 counts = Counter(numbers) result = [] for num in numbers: if counts[num] > n: result.append(num) counts[num] -= 1 # 每添加一次就减少计数,直到达到保留上限 print(result) # [1, 2, 2, 3, 3, 3, 3]
不要求顺序的简洁实现
如果不在意元素顺序,直接通过Counter的键值对生成结果:
from collections import Counter numbers = [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3] n = 2 counts = Counter(numbers) result = [] for num, cnt in counts.items(): if cnt > n: result.extend([num]*(cnt - n)) print(result) # [1, 2, 2, 3, 3, 3, 3]
一行代码写法
不要求顺序的一行写法
from collections import Counter numbers = [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3] n = 2 result = [num for num, cnt in Counter(numbers).items() for _ in range(max(0, cnt - n))] print(result) # [1, 2, 2, 3, 3, 3, 3]
保持原顺序的一行写法
可读性稍弱,但可以用默认字典跟踪已添加次数实现:
from collections import defaultdict numbers = [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3] n = 2 result = [num for num in numbers if (lambda d: d[num] < n and d.update({num: d[num]+1}))(defaultdict(int))]
内容的提问来源于stack exchange,提问作者Poonam
相关产品推荐
相关产品推荐

