【问题标题】:adding two consecutive numbers in a list在列表中添加两个连续的数字
【发布时间】:2012-02-28 00:16:25
【问题描述】:

如何在列表中添加两个连续的数字。

l = [1,2,3,4,5,6,7,8,9]

结果 = [3,7,11,15,9]

l = [1,2,3,4,5,6,7,8,9,10]

结果 = [3,7,11,15,19]

我可以使用简单的 for 循环轻松实现它。但 我怎样才能使用更多的pythonic方式来实现它。

【问题讨论】:

  • 我认为使用简单的for 循环来解决这个问题就像 Python 一样。

标签: python


【解决方案1】:

最好的方法!

我现在想更改对此的回答。比起 itertools 解决方案,我更喜欢它;我认为这是最少的代码(如果算上导入 itertools):

>>> x
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> if len(x) % 2: x.append(0)
... 
>>> map(sum, zip(x[::2], x[1::2]))
[3, 7, 11, 15, 9]

我知道有些人不喜欢 map,但我喜欢它 :) 我记得 reading somewhere 它比列表迭代更快。


我原来的答案:

>>> x=[1,2,3,4,5,6,7,8,9,10]
>>> [a+b for a,b in zip(x[::2], x[1::2])]
[3, 7, 11, 15, 19]

但没有给出奇数列表的答案:

>>> x=[1,2,3,4,5,6,7,8,9]
>>> [a+b for a,b in zip(x[::2], x[1::2])]
[3, 7, 11, 15]

杂牌修复:

>>> x   
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> result = [a+b for a,b in zip(x[::2], x[1::2])]
>>> if len(x) % 2: result.append(x[-1])
... 
>>> print result
[3, 7, 11, 15, 9]

:)

【讨论】:

  • 现在使用x = [1,2,3,4,5,6,7,8,9] 进行此操作。
  • x.append(0) 修改了原来的列表,可能有问题。
【解决方案2】:

您可以使用迭代器来避免中间列表:

>>> it = iter([1,2,3,4,5,6,7,8,9,10])
>>> [i + next(it, 0) for i in it]
[3, 7, 11, 15, 19]

它也适用于[1,2,3,4,5,6,7,8,9],因为next 将在StopIteration 上返回零。

【讨论】:

  • it = iter(l + [0]) 不够吗?
  • @eumiro 是的,如果它始终是一个列表。但这会创建另一个列表
  • 你是对的,当l 真的很大时,这可能很重要。
  • [i + next(it, 0) for i in it] 呢?
【解决方案3】:
import itertools as it    
[sum(r) for r in it.izip_longest(l[::2], l[1::2], fillvalue=0)]

返回奇数和偶数的等待值:

l = [1,2,3,4,5,6,7,8,9]    # [3, 7, 11, 15, 9]
l = [1,2,3,4,5,6,7,8,9,10] # [3, 7, 11, 15, 19]

更新:如果原始列表真的很大,您可以将简单切片替换为islice

[sum(r) for r in it.izip_longest(it.islice(l,0,None,2), it.islice(l,1,None,2), fillvalue=0)]

更新 2: 甚至更短、更通用的版本(没有 itertools)也来了:

l = [1,2,3,4,5,6,7,8,9,10]
n = 3

[sum(l[i:i+n]) for i in xrange(0, len(l), n)]
# returns: [6, 15, 24, 10]

【讨论】:

  • 现在步骤是 2。它的概括如何。说它可能是 2 或 3 或 4 等
【解决方案4】:

nsplit 拆分列表(n 项目一组):

>>> ls = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nsplit = lambda s, n: [s[i:i+n] for i in range(0, len(s), n)]

# [1+2, 3+4, 5+6, 7+8, 9]
>>> [sum(x) for x in nsplit(ls, 2)]
[3, 7, 11, 15, 9]

# [1+2+3, 4+5+6, 7+8+9]
>>> [sum(x) for x in nsplit(ls, 3)]
[6, 15, 24]

# [1+2+3+4, 5+6+7+8, 9]
>>> [sum(x) for x in nsplit(ls, 4)]
[10, 26, 9]

【讨论】:

    【解决方案5】:

    这是一种 Pythonic 且高效的方法,因为它只对 list 进行一次迭代:

    In [1]: l = [1,2,3,4,5,6,7,8,9]
    In [2]: from itertools import izip_longest
    In [3]: [sum (t) for t in izip_longest(* 2 * [iter(l)], fillvalue=0)]
    Out[3]: [3, 7, 11, 15, 9]
    

    请参阅:How does zip(*[iter(s)]*n) work in Python?,以了解关于相同 list 语法上奇怪的“2-iter”的解释。


    时间:

    % python -m timeit -c 'l = [1,2,3,4,5,6,7,8,9]
    from itertools import izip_longest
    [sum (t) for t in izip_longest(* 2 * [iter(l)], fillvalue=0)]
    '
    100000 loops, best of 3: 9.42 usec per loop
    

    【讨论】:

      【解决方案6】:
      from itertools import chain
      
      l = [1,2,3,4,5,6,7,8,9]
      it = chain(l,[0])
      result = list(x + next(it) for x in it)
      print l,'\n',result,'\n'
      
      
      l = [1,2,3,4,5,6,7,8,9,10]
      it = chain(l,[0])
      result = list(x + next(it) for x in it)
      print l,'\n',result,'\n'
      
      
      
      l = [1,2,3,4,5,6,7,8,9]
      it = chain(l,[0,0])
      result = list(x + next(it) + next(it) for x in it)
      print l,'\n',result,'\n'
      
      l = [1,2,3,4,5,6,7,8,9,10]
      it = chain(l,[0,0])
      result = list(x + next(it)+ next(it) for x in it)
      print l,'\n',result,'\n'
      

      生产

      [1, 2, 3, 4, 5, 6, 7, 8, 9] 
      [3, 7, 11, 15, 9] 
      
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
      [3, 7, 11, 15, 19] 
      
      [1, 2, 3, 4, 5, 6, 7, 8, 9] 
      [6, 15, 24] 
      
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
      [6, 15, 24, 10]
      

      但我更喜欢 JBernardo - glglgl 的解决方案

      【讨论】:

        猜你喜欢
        • 2015-11-22
        • 2015-07-01
        • 2020-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多