【问题标题】:Indexing with List of Indices to Exclude使用要排除的索引列表进行索引
【发布时间】:2013-08-29 08:07:46
【问题描述】:

这与其他一些问题(Explicitly select items from a Python list or tupleGrabbing specific indices of a list in Python)类似,但我希望做相反的事情:

什么是指定索引列表/元组以排除而不是选择的简洁方法?我正在考虑类似于 R 或 MATLAB 的东西,您可以在其中指定要排除的索引,例如:

vector1 <- c('a', 'b', 'c', 'd')
vector2 <- vector1[-1] # ['b', 'c', 'd']
vector3 <- vector1[c(-1, -2)] # ['c', 'd']

有没有在 Python 中完成同样事情的好方法?抱歉,如果这是一个骗局,我不确定要搜索什么。

【问题讨论】:

    标签: python list indexing


    【解决方案1】:
    >>> to_exclude = {1, 2}
    >>> vector = ['a', 'b', 'c', 'd']
    >>> vector2 = [element for i, element in enumerate(vector) if i not in to_exclude]
    

    这里的技巧是:

    • 使用列表推导将一个列表转换为另一个列表。 (您也可以使用 filter 函数,尤其是当您要过滤的谓词已经作为一个名称很好的函数存在时。)
    • 使用enumerate 将每个元素及其索引放在一起。
    • 对任何SetSequence* 类型使用in 运算符来决定过滤哪些类型。 (如果有很多值,set 是最有效的,并且可能在概念上是正确的答案......但对于少数几个来说真的没关系;如果你已经有一个包含 4 个索引的列表或元组它,这也是一个“SetSequence”,所以你可以使用它。)

    * 从技术上讲,任何Container 都可以。但是大多数不是SetSequenceContainers 在这里会很傻。

    【讨论】:

    • 啊哈,当然。感谢您的详细解释(如果允许,我会接受)。
    【解决方案2】:
    import numpy
    target_list = numpy.array(['1','b','c','d','e','f','g','h','i','j'])
    to_exclude = [1,4,5]
    print target_list[~numpy.in1d(range(len(target_list)),to_exclude)]
    

    因为 numpy 很有趣

    【讨论】:

    • 另外,如果您要将 MATLAB 代码翻译成 Python,您可能应该查看 numpy 而不是原生列表和循环...
    【解决方案3】:

    使用np.delete

    In [38]: a
    Out[38]: array([ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13])
    
    In [39]: b
    Out[39]: [3, 4, 5, 9]
    
    In [40]: a[b]
    Out[40]: array([ 7,  8,  9, 13])
    
    In [41]: np.delete(a, b)
    Out[41]: array([ 4,  5,  6, 10, 11, 12])
    

    【讨论】:

      【解决方案4】:

      使用enumerate() 并排除您要删除的任何索引:

      [elem for i, elem in enumerate(inputlist) if i not in excluded_indices]
      

      为了提高性能,如果excluded_indicesset,那将是最快的。

      【讨论】:

      • set 实际上不会比 list 快,直到有多个元素(从上一个问题来看,截止值在 3 到 12 之间的任何字符串,具体取决于您的实现)。但从概念上讲,无论如何它更有意义。
      • @abarnert:这不也取决于输入列表中的元素数量吗?对于这个过滤器,如果excluded_indices 也被排序或随机化,它可能会有所不同;我有点怀疑截止值是接近 12;集合查找(主要是哈希计算和查找)的固定成本真的那么高吗?
      • 据我隐约记得,在 Python 2.7 中有非常大的 unicode 对象,我发现了一个截止值在 6 到 7 之间的案例……但其他人发现了一个几乎两倍高的案例,可能在不同的 Python 实现中。当然要注意“带字符串”;散列整数要快得多,甚至是巨大的整数,所以我希望它在最坏的情况下大约是 2-3 ......而且我不确定排序会有什么不同(除非你想要使用 bisect 的第三个实现或一棵树什么的)。
      • @abarnert:Hrm,你说得对,排序没有区别,无论顺序如何,所有搜索的总成本都是一样的。
      • 另外,输入元素的数量会有什么影响?这将是线性的,除了少数边缘情况(例如,如果你有很多对少量不同的慢散列内置对象的引用,最重要的因素可能是 unique 的数量 元素。)
      【解决方案5】:
      numpy.delete(original_list,index_of_the_excluded_elements)
      

      注意,在python中,索引是从0开始的,所以对于问题中的例子,代码应该是:

      import numpy as np
      vector1=['a', 'b', 'c', 'd']
      vector2 =np.delete(vector1,[0]) # ['b', 'c', 'd']
      vector3 =np.delete(vector1,[0,1]) # ['c', 'd']
      

      【讨论】:

        【解决方案6】:

        我将采用不同的方法,使用itemgetter。只是为了好玩:)

        from operator import itemgetter
        
        def exclude(to_exclude, vector):
            "Exclude items with particular indices from a vector."
            to_keep = set(range(len(vector))) - set(to_exclude)
            return itemgetter(*to_keep)(vector)
        

        【讨论】:

        • 虽然这看起来可行,但集合是无序的。因此,例如,itemgetter(*{2, 3, 10})(list(range(11))) 可能会产生 (10, 2, 3)
        猜你喜欢
        • 2012-09-07
        • 1970-01-01
        • 2022-07-05
        • 2015-07-25
        • 1970-01-01
        • 2022-01-08
        • 2017-06-19
        • 2012-03-27
        • 2020-03-29
        相关资源
        最近更新 更多