代码之家  ›  专栏  ›  技术社区  ›  telliott99

python:使用itertools将列表拆分为组的参数

  •  5
  • telliott99  · 技术社区  · 15 年前

    这是一个关于使用标准库的快速代码的相对优点的问题,但是与手动滚动的替代方案相比,它是模糊的(至少对我来说)。在这 thread (以及它重复的其他方法),将列表分成组的“pythonic”方法似乎是使用itertools,如下面代码示例中的第一个函数(在 ΤΖΩΤΖΙΟΥ )

    我喜欢第二个功能的原因是我能理解它是如何工作的,如果我不需要填充(比如说,把DNA序列转换成密码子),我可以在瞬间从记忆中复制出来。

    ITertools的速度更好。特别是如果我们不想返回列表,或者我们想填充最后一个条目,itertools会更快。

    还有哪些其他的参数支持标准库解决方案?

    from itertools import izip_longest
    
    def groupby_itertools(iterable, n=3, padvalue='x'):
        "groupby_itertools('abcde', 3, 'x') --> ('a','b','c'), ('d','e','x')"
        return izip_longest(*[iter(iterable)]*n, fillvalue=padvalue)
    
    def groupby_my(L, n=3, pad=None):
        "groupby_my(list('abcde'), n=3, pad='x') --> [['a','b','c'], ['d','e','x']]"
        R = xrange(0,len(L),n)
        rL = [L[i:i+n] for i in R]
        if pad:
            last = rL[-1]
            x = n - len(last)
            if isinstance(last,list):
                rL[-1].extend([pad] * x)
            elif isinstance(last,str):
                rL[-1] += pad * x
        return rL
    

    时机:

    $ python -mtimeit -s 'from groups import groupby_my, groupby_itertools;  L = list("abcdefghijk")' 'groupby_my(L)'
    100000 loops, best of 3: 2.39 usec per loop
    
    $ python -mtimeit -s 'from groups import groupby_my, groupby_itertools;  L = list("abcdefghijk")' 'groupby_my(L[:-1],pad="x")'
    100000 loops, best of 3: 4.67 usec per loop
    
    $ python -mtimeit -s 'from groups import groupby_my, groupby_itertools;  L = list("abcdefghijk")' 'groupby_itertools(L)'
    1000000 loops, best of 3: 1.46 usec per loop
    
    $ python -mtimeit -s 'from groups import groupby_my, groupby_itertools;  L = list("abcdefghijk")' 'list(groupby_itertools(L))'
    100000 loops, best of 3: 3.99 usec per loop
    

    编辑:我会在这里更改函数名(见Alex的答案),但是有太多的函数名我决定发布这个警告。

    2 回复  |  直到 15 年前
        1
  •  15
  •   Alex Martelli    15 年前

    当您重新使用标准库中的工具,而不是通过自己从头开始对它们进行编码来“重新发明轮子”时,您不仅得到了很好的优化和调优软件(有时令人惊讶的是,在 itertools 组件):更重要的是,您获得了大量不需要自己测试、调试和维护的功能——您充分利用了许多优秀程序员为标准库做出贡献的所有测试、调试和维护工作!

    因此,在理解标准库所提供的内容方面的投资可以迅速地、多次地回报自己——而且您将能够“从内存中复制”和重新设计的车轮代码,实际上,由于更多的重用,可能会更好。

    顺便说一下,术语“group by”对于大多数程序员来说有一个定义明确的惯用含义,这要归功于它在SQL中的使用(以及在 迭代工具 本身):因此,我建议您避免将其用于完全不同的用途——这只会在您与任何其他人合作时产生混乱(希望经常是,自独奏全盛时期以来,“牛仔”程序员早已不复存在——另一个赞成标准和反对车轮改造的论点;—)。

    最后,docstring与函数的签名不匹配——参数顺序错误;-)。

        2
  •  5
  •   unutbu    15 年前

    花在学习Python基础知识上的时间将在稍后的SPADES中得到回报。 因此,学习itertools,以及groupby是如何工作的。 不仅是使用ITertools可能比任何手动解决方案都要快, 它将帮助您将来编写更好的代码。