【问题标题】:Python enumerate reverse index onlyPython仅枚举反向索引
【发布时间】:2016-12-08 21:03:23
【问题描述】:

我正在尝试反转enumerate 给出的索引,同时保留被枚举列表的原始顺序。

假设我有以下内容:

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

如果我列举这个,我会得到以下信息:

>> list(enumerate(range(5)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

但是我想反转 enumerate 提供的索引,以便我得到:

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

到目前为止,我有以下代码:

reversed(list(enumerate(reversed(range(5)))))

我只是想知道是否有更简洁的方法可以做到这一点?

【问题讨论】:

    标签: python python-3.x reverse enumerate


    【解决方案1】:

    使用 zip 代替反向范围怎么样?

    >>> zip(range(9, -1, -1), range(10))
    [(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)]
    
    
    >>> def reversedEnumerate(l):
            return zip(range(len(l)-1, -1, -1), l)
    >>> reversedEnumerate(range(10))
    [(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)]
    

    正如@julienSpronk 建议的那样,使用izip 来获取生成器,也可以使用xrange

    import itertools
    >>> import itertools
    >>> def reversedEnumerate(l):
    ...     return itertools.izip(xrange(len(l)-1, -1, -1), l)
    ...     
    >>> reversedEnumerate(range(10))
    <itertools.izip object at 0x03749760>
    >>> for i in reversedEnumerate(range(10)):
    ...     print i
    ...     
    (9, 0)
    (8, 1)
    (7, 2)
    (6, 3)
    (5, 4)
    (4, 5)
    (3, 6)
    (2, 7)
    (1, 8)
    (0, 9)
    

    【讨论】:

    • itertools.izip 获取生成器
    【解决方案2】:

    我不知道这个解决方案是否更适合你,但至少它更短:

    >>> [(4 - x, x) for x in range(5)]
    [(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
    

    【讨论】:

      【解决方案3】:

      只需获取列表的长度并从中减去索引...

      L = range(5)
      
      for i, n in L:
          my_i = len(L) -1 - i
          ...
      

      或者如果你真的需要一个生成器:

      def reverse_enumerate(L):
         # Only works on things that have a len()
         l = len(L)
         for i, n in enumerate(L):
             yield l-i-1, n
      

      enumerate() 不可能这样做,因为它适用于通用迭代器。例如,您可以向它传递无限迭代器,甚至没有“反向索引”。

      【讨论】:

        【解决方案4】:

        假设您的列表不长并且您不会遇到性能错误,您可以使用list(enumerate(range(5)[::-1]))[::-1]

        测试:

        >>> list(enumerate(range(5)[::-1]))[::-1] [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]

        【讨论】:

        • 据我所知,我提供了最简洁的方法。不过,这个问题有点意思。
        • 他希望索引被反转,而不是列表
        • 糟糕!正确的。固定。
        • 这也是我会做的。我个人什至不关心最后的反转......
        【解决方案5】:

        其实我使用的逻辑和@RemcoGerlich 一样,但是我直接使用list comprehension,这使得代码现在变成了1-liner:

        def generatelist(x):
            return [(x-1-i,n) for i,n in enumerate(range(x))]
        

        关于选择generatorlist comprehension的困境,here是建议的方式:

        基本上,如果您所做的只是迭代一次,请使用生成器表达式。如果您想存储和使用生成的结果,那么最好使用列表推导式。

        【讨论】:

          【解决方案6】:

          如果你打算多次重复使用它,你可以制作自己的生成器:

          def reverse_enum(lst):
              for j, item in enumerate(lst):
                  yield len(lst)-1-j, item
          
          print list(reverse_enum(range(5)))
          # [(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
          

          def reverse_enum(lst):
              return ((len(lst)-1-j, item) for j, item in enumerate(lst))
          

          【讨论】:

            【解决方案7】:

            Python 2

            import itertools
            
            def reversed_enumerate(seq):
                return itertools.izip(reversed(range(len(seq))), reversed(seq))
            

            Python 3

            zip 替换itertools.izip :)

            【讨论】:

              【解决方案8】:

              只要在使用 i 的地方使用 len(lst)-i。或:

              [(len(range(5)) - x, x) for x in range(5)]
              

              【讨论】:

              • -(i+1)-1-i
              【解决方案9】:
              values = 'abcde'
              
              for i, value in zip(reversed(range(len(values))), values):
                  print(i, value)
              

              解释:

              values = 'abcde'
              
              values_len = len(values) # 5
              indexes = range(values_len) # [0, 1, 2, 3, 4]
              reversed_indexes = reversed(indexes) # [4, 3, 2, 1, 0]
              
              # combine reversed indexes and values
              reversed_enumerator = zip(reversed_indexes, values)
              
              for i, value in reversed_enumerator:
                  print(i, value)
              

              【讨论】:

              • 请描述您进行了哪些更改以及更改的原因,以帮助其他人识别问题并理解此答案
              【解决方案10】:

              我们可以使用 enumerate 和 len:

              $ cat enumerate.py 
              
              
              arr = ['stone', 'cold', 'steve', 'austin']
              for i, val in enumerate(arr):
                  print ("enu {} val {}".format(i, val))
              for i, val in enumerate(arr):
                  print ("enu {} val {}".format(len(arr) - i - 1, val))
              $  python enumerate.py 
              enu 0 val stone
              enu 1 val cold
              enu 2 val steve
              enu 3 val austin
              enu 3 val stone
              enu 2 val cold
              enu 1 val steve
              enu 0 val austin
              $  
              

              【讨论】:

                猜你喜欢
                • 2011-10-17
                • 1970-01-01
                • 1970-01-01
                • 2022-12-21
                • 1970-01-01
                • 2021-04-18
                • 2013-09-23
                • 2014-07-17
                • 2012-07-01
                相关资源
                最近更新 更多