【问题标题】:Better solution to get differences between list elements [duplicate]获得列表元素之间差异的更好解决方案[重复]
【发布时间】:2014-07-22 14:34:37
【问题描述】:

我不是在寻找解决方案(我有两个 ;)),而是在洞察力比较每个解决方案的优缺点,考虑到 python 的内部结构。谢谢!

与同事一起,我们希望为所有元素提取两个连续列表元素之间的差异。所以,对于列表:

[1,2,4]

预期的输出是:

[1,2]

(因为 2-1 = 1,而 4-2 = 2)。

我们提供了两种解决方案,我不确定它们如何比较。第一个非常类似于 C,它将列表视为一个表格,并减去两个连续列表元素之间的差异。

res = []
for i in range(0, len(a)-1):
    res.append(a[i+1] - a[i])

第二个是(对于列表“l”),我认为,更pythonic:

[j - i for i,j in zip(l[:-1], l[1:])]

但是,构建两个列表副本然后提取差异不是效率低得多吗? Python 如何在内部处理这个问题?

感谢您的见解!

【问题讨论】:

  • 你应该发布这两个解决方案,它们会更容易比较。
  • 如果您不想构建列表副本,请使用itertools.izipitertools.islice
  • @TheSoundDefense :确实,谢谢。我已经编辑了我的帖子。
  • 这些列表是否足够大以关心性能?只写最易读的版本和可维护的版本。
  • 注意:您可以通过使用l 而不是l[:-1] 轻松提高第二种解决方案的性能。 zipshortest 输入完成时已经终止,因此您必须删除最后一个元素。

标签: python


【解决方案1】:

使用发电机:

def diff_elements(lst):
    """
    >>> list(diff_elements([]))
    []
    >>> list(diff_elements([1]))
    []
    >>> list(diff_elements([1, 2, 4, 7]))
    [1, 2, 3]
    """
    as_iter = iter(lst)
    last = next(as_iter)
    for value in as_iter:
        yield value - last
        last = value

这具有以下优点:

  1. 可读性强,并且
  2. 处理无限大的数据集。

【讨论】:

    【解决方案2】:

    如果我理解你的问题,我建议你使用类似的东西:

    diffList = lambda l: [(l[i] - l[i-1]) for i in range(1, len(l))]
    answer = diffList( [ 1,2,4] )
    

    此函数将为您提供一个列表,其中包含输入列表中所有连续元素之间的差异。

    这与您的第一种方法相似(并且仍然有点pythonic)比第二种方法更有效。

    【讨论】:

      【解决方案3】:

      没有 lambda:

      [l[i+1] - l[i] for i in range(len(l) - 1)]
      

      例如:

      >>> l = [1, 4, 8, 15, 16]
      >>> [l[i+1] - l[i] for i in range(len(l) - 1)]
      [3, 4, 7, 1]
      

      快一点,如您所见(编辑:在https://stackoverflow.com/a/2400875/1171280 中添加投票最多的解决方案):

      >>> import timeit
      >>> 
      >>> s = """\
      ...     l = [1, 4, 7, 15, 16]
      ...     [l[i+1] - l[i] for i in range(len(l) - 1)]
      ... """
      
      
      >>> r = """\
      ...     l = [1, 4, 7, 15, 16]
      ...     [j - i for i,j in zip(l[:-1], l[1:])]
      ... """
      
      >>> t = """\
      ...     l = [1, 4, 7, 15, 16]
      ...     [j-i for i, j in itertools.izip(l[:-1], l[1:])]
      ... """
      
      >>> timeit.timeit(stmt=s, number=100000)
      0.09615588188171387
      >>> timeit.timeit(stmt=s, number=100000)
      0.09774398803710938
      >>> timeit.timeit(stmt=s, number=100000)
      0.09683513641357422
      #-------------
      >>> timeit.timeit(stmt=r, number=100000)
      0.14137601852416992
      >>> timeit.timeit(stmt=r, number=100000)
      0.12511301040649414
      >>> timeit.timeit(stmt=r, number=100000)
      0.12285017967224121
      #-------------
      >>> timeit.timeit(stmt=t, number=100000)
      0.11506795883178711
      >>> timeit.timeit(stmt=t, number=100000)
      0.11677718162536621
      >>> timeit.timeit(stmt=t, number=100000)
      0.11829996109008789
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-31
        • 2016-01-21
        • 1970-01-01
        • 1970-01-01
        • 2017-09-10
        • 2014-05-14
        • 1970-01-01
        相关资源
        最近更新 更多