科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件Python: 替代uniq命令函数groupby

Python: 替代uniq命令函数groupby

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

groupby函数可满足各种需求,但在Python中复制UNIX过滤器uniq是它的最佳用途之一。groupby可用于处理各种问题,如果你只能记住一个itertools函数,那么无疑groupby可帮助你完成最多任务。

作者:开发者在线 来源:开发者在线 2007年8月13日

关键字: Nick Gibson Group by uniq python

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共19页)

groupby函数可满足各种需求,但在Python中复制UNIX过滤器uniq是它的最佳用途之一。

上周我们讨论了itertools模块,并指出使用其基于迭代器的函数比从零开始更加快捷。有一个例子说明使用itertools.takewhile的函数的速度要比使用itertools.groupby的函数快得多。我们收到一些反馈,询问:既然groupby只是其它功能的一个更缓慢的版本,那我们有什么理由要应用它呢?

groupby可用于处理各种问题,如果你只能记住一个itertools函数,那么无疑groupby可帮助你完成最多任务。

例如,前一篇文章中的压缩(compress)函数可以简单写成:

def compress(l):

return [a for a,b in groupby(l)]

这并不是速度最快的代码,但如果你的数据集不是过于庞大,那么它的速度会相当快。我们在一个由两百万个数字组成的列表中对它进行测试,结果发现二者的时间差不到一分钟。

包装(pack)函数也同样简单:

def pack(l):

return [list(b) for a,b in groupby(l)]

我们来回忆这些函数的功能:

>>> import random

>>> from itertools import *

>>> x = [random.randint(0,5) for x in range(20)]

>>> x

[3, 5, 1, 2, 4, 4, 4, 1, 4, 5, 2, 5, 3, 4, 5, 0, 5, 0, 2, 1]

>>> [(a,list(b)) for a,b in groupby(x)]

[(3, [3]), (5, [5]), (1, [1]), (2, [2]), (4, [4, 4, 4]), (1, [1]), (4, [4]), (5, [5]), (2, [2]), (5, [5]), (3, [3]), (4, [4]), (5, [5]), (0, [0]), (5, [5]), (0, [0]), (2, [2]), (1, [1])]

>>> compress(x)

[3, 5, 1, 2, 4, 1, 4, 5, 2, 5, 3, 4, 5, 0, 5, 0, 2, 1]

>>> pack(x)

[[3], [5], [1], [2], [4, 4, 4], [1], [4], [5], [2], [5], [3], [4], [5], [0], [5], [0], [2], [1]]

如果你熟悉终端,你会发现这非常类似于unix的”uniq”命令,它对文本行进行压缩。uniq常常和sort命令组合使用,我们可以把上例写成这样:

>>> [a for a,b in groupby(sorted(x))]

[0, 1, 2, 3, 4, 5]

>>> [list(b) for a,b in groupby(sorted(x))]

[[0, 0], [1, 1, 1], [2, 2, 2], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5]]

uniq的另一个常见用法就是使用"sort | uniq -c",计算列表中每一个项目的出现次数。你也可以用groupby完成这种功能:

>>> [(a,len(list(b))) for a,b in groupby(sorted(x))]

[(0, 2), (1, 3), (2, 3), (3, 2), (4, 5), (5, 5)]

如果你在字典中需要那些信息——例如对象和出现次数之间的映射,你只需把那个列表封装在dict()对象中:

>>> dict([(a,len(list(b))) for a,b in groupby(sorted(x))])

{0: 2, 1: 3, 2: 3, 3: 2, 4: 5, 5: 5}

今天议程的最后一点,仅在列表中返回副本——就像“uniq -d”一样。我们正在使用列表推导(list comprehension),因此我们可以使用内嵌过滤使群包含几个元素:

>>> [a for a,b in groupby(x) if len(list(b)) > 1]

[4]

编写替代uniq命令的代码只是groupby的用途之一。查看Python库文档了解更多信息。

更正:原始版本遗漏了压缩(compress)和包装(wrap)函数中的返回语句。感谢读者指出这一点。

责任编辑:德东

查看本文国际来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章