【问题标题】:Increment the next element based on previous element根据前一个元素递增下一个元素
【发布时间】:2016-03-29 02:17:02
【问题描述】:

循环遍历列表时,您可以使用列表的当前项。例如,如果您想将某些项目替换为其他项目,您可以使用:

a=['a','b','c','d','e']

b=[]
for i in a:
    if i=='b':
       b.append('replacement')     
    else:   
        b.append(i)

print b
['a', 'replacement', 'c', 'd', 'e']

但是,我希望替换某些值不是基于索引i,而是基于索引i+1。我已经尝试了很多年,但我似乎无法让它发挥作用。我想要这样的东西:

c=['a','b','c','d','e']

d=[]
for i in c:
    if i+1=='b':
       d.append('replacement')     
    else:   
        d.append(i)


print d

d=['replacement','b','c','d','e']

有什么办法可以做到吗?

【问题讨论】:

    标签: python list for-loop indexing


    【解决方案1】:

    使用list comprehensionenumerate

    >>> ['replacement' if a[i+1]=='b' else v for i,v in enumerate(a[:-1])]+[a[-1]]
    ['replacement', 'b', 'c', 'd', 'e']
    

    代码替换下一个元素为b 的所有元素。然而,为了处理最后一个索引并防止IndexError,我们只需附加最后一个元素并循环直到倒数第二个元素。


    没有列表理解

    a=['a','b','c','d','e']
    d=[]
    for i,v in enumerate(a[:-1]):
        if a[i+1]=='b':
            d.append('replacement')     
        else:   
            d.append(v)
    d.append(a[-1])
    print d
    

    【讨论】:

      【解决方案2】:

      在 Python 中不迭代索引通常是更好的风格。解决此类问题的常用方法是使用zip(或itertools 中的类似izip_longest)一次查看多个值:

      In [32]: from itertools import izip_longest
      
      In [33]: a=['a','b','c','d','e']
      
      In [34]: b = []
      
      In [35]: for c, next in izip_longest(a, a[1:]):
         ....:     if next == 'd':
         ....:         b.append("replacement")
         ....:     else:
         ....:         b.append(c)
         ....:
      
      In [36]: b
      Out[36]: ['a', 'b', 'replacement', 'd', 'e'] 
      

      【讨论】:

        【解决方案3】:

        尝试使用当前元素的索引来检查列表中的下一个元素。 替换

        if i+1=='b':
        

        if c[c.index(i)+1]=='b':
        

        【讨论】:

        • 这不是一个非常 Pythonic 的解决方案。
        【解决方案4】:

        我认为您的帖子中的列表索引和列表元素之间存在混淆。在您编写的循环中,i 将是实际元素(例如'b')而不是索引,因此i+1 没有意义,并且会引发TypeError 异常。

        我认为您可以对示例进行的最小更改之一是:

        c = ['a', 'b', 'c', 'd', 'e']
        
        d = []
        
        for i, el in enumerate(c[:-1]):
            if c[i + 1] == 'b':
                d.append('replacement')     
            else:
                d.append(el)
        
        print d
        
        # Output...
        # ['replacement', 'b', 'c', 'd']
        

        此外,您应该如何处理边界还没有定义。特别是当i 指向最后一个元素'e' 时,i+1 应该指向什么?这里有很多可能的答案。在上面的示例中,我选择了一个选项,即提前一个元素结束迭代(因此我们永远不会指向最后一个元素 e)。

        如果我这样做,我会做类似于其他答案组合的事情:

        c = ['a', 'b', 'c', 'd', 'e']
        
        
        d = ['replacement' if next == 'b' else current
             for current, next in zip(c[:-1], c[1:]) ]
        
        print d
        
        # Output...
        # ['replacement', 'b', 'c', 'd']
        

        我使用列表推导来避免循环,并在列表中使用zip 并使用移位列表来避免显式索引。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-16
          • 1970-01-01
          • 2015-03-27
          • 2013-01-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多