【问题标题】:Python List Slicing with Arbitrary Indices具有任意索引的 Python 列表切片
【发布时间】:2012-02-24 17:42:19
【问题描述】:

有没有更好的方法从 python 中的列表中提取任意索引?

我目前使用的方法是:

a = range(100)
s = [a[i] for i in [5,13,25]]

其中 a 是我要切片的数组,[5,13,​​25] 是我要获取的元素。它似乎比 Matlab 等价物更冗长:

a = 0:99;
s = a([6,14,26])

【问题讨论】:

  • “它似乎比 Matlab 详细得多”。它们是不同的语言。你期待什么? Python 比 Java更少 冗长。
  • Python 索引是从 0 开始的。您的5 表示第六个元素。基于 1 的语言将在那里有一个6。 Matlab 怎么需要4?它是从 -1 开始的吗?
  • 这种方式其实可读性很强,我喜欢。

标签: python list slice


【解决方案1】:

没有“现成”的方式——你做的方式很天真,你可以使用它。 如果你的代码中有很多这样的东西,你可能想使用一个 list 的子类,它使用类似于 matlabs 的语法——它可以用几行代码完成,主要的负担是你必须工作总是使用这个新类而不是内置列表。

class MyList(list):
    def __getitem__(self, index):
        if not isinstance(index, tuple):
            return list.__getitem__(self, index)
        return [self[i] for i in index]

在控制台上:

>>> m = MyList(i * 3 for i in range(100))
>>> m[20, 25,60]
[60, 75, 180]

【讨论】:

    【解决方案2】:

    看来你会这样做:

        a = list(range(99)) 
        s = [a[5], a[13], a[25]] 
    

    这似乎与 matlab 版本几乎相同。

    【讨论】:

    • 如果我不得不猜测,可能是因为这个答案在 Python 3 中不起作用(a 不可索引)。
    【解决方案3】:

    如果您是 Matlab 用户,但想使用 Python,请查看numpy

    In [37]: import numpy as np
    
    In [38]: a = np.arange(100)
    
    In [39]: s = a[[5,13,25]]
    
    In [40]: s
    Out[40]: array([ 5, 13, 25])
    

    这里是comparison of NumPy and Matlab,这里是常用Matlab commands and their equivalents in NumPy的表。

    【讨论】:

      【解决方案4】:
      >>> from operator import itemgetter
      >>> a = range(100)
      >>> itemgetter(5,13,25)(a)
      (5, 13, 25)
      

      【讨论】:

      • 如果使用列表作为索引,请注意此边缘条件:indexes = [1,]; itemgetter(*indexes)(a) ----> 返回一个整数,而不是一个元组
      • 谢谢!有了这个功能,想必还是第一次遇到真正需要unpack *操作符。
      • 很好,我希望这是默认行为 - 如果它会遇到麻烦并告诉我它不能接受元组索引,它不妨先尝试使用元组。在习惯了以类似方式寻址 IPython 集群节点的想法后,我来到了这里。
      • 注意@DarrenRinger 在这里的意思是,如果你想要的索引在一个列表中,你会写itemgetter(*indices)(list)
      【解决方案5】:

      这里是被接受的优秀@John La Rooy answer 的更强大版本。它通过了提供的文档测试。它总是返回一个列表。

      def slice_by_index(lst, indexes):
          """Slice list by positional indexes.
      
          Adapted from https://stackoverflow.com/a/9108109/304209.
      
          Args:
              lst: list to slice.
              indexes: iterable of 0-based indexes of the list positions to return.
      
          Returns:
              a new list containing elements of lst on positions specified by indexes.
      
          >>> slice_by_index([], [])
          []
          >>> slice_by_index([], [0, 1])
          []
          >>> slice_by_index(['a', 'b', 'c'], [])
          []
          >>> slice_by_index(['a', 'b', 'c'], [0, 2])
          ['a', 'c']
          >>> slice_by_index(['a', 'b', 'c'], [0, 1])
          ['a', 'b']
          >>> slice_by_index(['a', 'b', 'c'], [1])
          ['b']
          """
          if not lst or not indexes:
              return []
          slice_ = itemgetter(*indexes)(lst)
          if len(indexes) == 1:
              return [slice_]
          return list(slice_)
      

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        • 2012-12-16
        • 1970-01-01
        • 2021-02-11
        • 1970-01-01
        • 2012-06-14
        相关资源
        最近更新 更多