Python 列表去重的4种方式及性能对比

列表去重是Python中一种常见的处理方式,任何编程场景都可能会遇到需要列表去重的情况。

列表去重的方式有很多,本文将一一讲解他们,并进行性能的对比。

让我们先制造一些简单的数据,生成0到99的100万个随机数:

from random import randrangeDUPLICATES = [randrange(100) for _ in range(1000000)]

接下来尝试这4种去重方式中最简单直观的方法:

1.新建一个数组,遍历原数组,如果值不在新数组里便加入到新数组中。

# 第一种方式def easy_way():    unique = []    for element in DUPLICATES:        if element not in unique:            unique.append(element)    return unique

进入ipython使用timeit计算其去重耗时:

%timeit easy_way()# 1.16 s ± 137 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

平均耗时在1.16秒左右,但是在这个例子中我们使用了数组作为存储对象,实际上如果我们改成集合存储去重后的结果,性能会快不少:

def easy_way():    unique = set()    for element in DUPLICATES:        if element not in unique:            unique.add(element)    return unique
%timeit easy_way()# 48.4 ms ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在48毫秒左右,改善明显,这是因为集合和数组的内在数据结构完全不同,集合使用了哈希表,因此速度会比列表快许多,但缺点在于无序。

接下来看看第2种方式:

2.直接对数组进行集合转化,然后再转回数组:

# 第二种去重方式def fast_way()    return list(set(DUPLICATES))

耗时:

%timeit fast_way()# 14.2 ms ± 1.73 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

平均耗时14毫秒,这种去重方式是最快的,但正如前面所说,集合是无序的,将数组转为集合后再转为列表,就失去了原有列表的顺序。

如果现在有保留原数组顺序的需要,那么这个方式是不可取的,怎么办呢?

3.保留原有数组顺序的去重

使用dict.fromkeys()函数,可以保留原有数组的顺序并去重:

def save_order():    return list(dict.fromkeys(DUPLICATES))

当然,它会比单纯用集合进行去重的方式耗时稍微久一点:

%timeit save_order()# 39.5 ms ± 8.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在39.5毫秒,我认为这是可以接受的耗时,毕竟保留了原数组的顺序。

但是,dict.fromkeys()仅在Python3.6及以上才支持。

如果你是Python3.6以下的版本,那么可能要考虑第四种方式了。

4. Python3.6以下的列表保留顺序去重

在Python3.6以下,其实也存在fromkeys函数,只不过它由collections提供:

from collections import OrderedDictdef save_order_below_py36():    return list(OrderedDict.fromkeys(DUPLICATES))

耗时:

%timeit save_order_below_py36()# 71.8 ms ± 16.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

平均耗时在72毫秒左右,比 Python3.6 的内置dict.fromkeys()慢一些,因为OrderedDict是用纯Python实现的。

文末福利

明哥整理了 21 张 Python 代码速查表,每一张都是国外的大师总结的,非常实用 ~

还有 2 张高清的 PyCharm 快捷键一览图,一张 Windows ,一张 Mac,放在桌面上,需要的时候打开一查,非常方便。。

怎么获取呢?

(0)

相关推荐

  • 用迭代器模块为Python提速

    Python官方文档用'高效的循环'来形容itertools模块,有些tools会带来性能提升,而另外一些tools并不快,只是会节省一些开发时间而已,如果滥用还会导致代码可读性变差.我们不妨把ite ...

  • 机器学习:爱因斯坦的小贡献

    怎么,爱因斯坦(Albert Einstein)那会儿就有数据科学了吗? 倒不是这个意思,爱因斯坦也没有提出什么数学理论,但他提出了一个针对数学公式的符号简化办法,即爱因斯坦求和约定(Einstein ...

  • 列表推导式:简洁高效更具 Python 风格的列表创建方法

    我们在<Python 中的列表和元组>中已经详细介绍了列表(list)的基本特性和使用方法,本文将着重介绍一种 Python 中用于创建 list 的简洁高效的语法形式:列表推导式. Py ...

  • Python实现屏幕截图的两种方式

    使用windows API 使用PIL中的ImageGrab模块 下面对两者的特点和用法进行详细解释. 一.Python调用windows API实现屏幕截图 好处是 灵活 速度快 缺点是: 写法繁琐 ...

  • Python实现单例模式的5种方式

    写在前面 学究嘛,就记录一下; 本质都是通过设置一个标志位来实现, 通俗的讲就是当第一次实例化时, 记录下"已经实例化了", 当再次实例化时, 将"记录"的地址 ...

  • 怎么通过python挣外快,通过Python挣外快的几种方式

    当今收入低于5000的人至少占到40%,完全不够养活一家人,而且很多小伙伴其实空余时间比较多,特别是大学生,零花钱又不够花,都想靠业余时间找点轻松的活增加收入,但是却没门路,现在的社会中,只要掌握一个 ...

  • Python格式化输出的三种方式

    一.占位符 程序中经常会有这样场景:要求用户输入信息,然后打印成固定的格式 比如要求用户输入用户名和年龄,然后打印如下格式:My name is xxx,my age is xxx. 很明显,用逗号进 ...

  • 最全总结!聊聊 Python 调用 JS 的几种方式

    最全总结!聊聊 Python 调用 JS 的几种方式

  • 涨见识了,在终端执行 Python 代码的 6 种方式!

    原作:BRETT CANNON 译者:豌豆花下猫@Python猫 英文:https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the- ...

  • appium+python自动化46-安装app三种方式

    前言 adb安装 1.在app自动化之前,首先手机上有要被测试的app,如何把电脑本地上的app安装到手机上呢?可以在运行自动化代码前,在cmd输入adb指令,把电脑app安装到手机上 adb ins ...

  • Python爬虫:Scrapy从脚本运行爬虫的5种方式!

    Python爬虫:Scrapy从脚本运行爬虫的5种方式! Python编程学习圈 1周前 关注+星标,每天学习Python新技能 测试环境 一.命令行运行爬虫 1.编写爬虫文件 baidu.py 图片 ...

  • Python打印九九乘法表有几种方式?

    公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助! 小猿会从最基础的面试题开始, ...