在python中访问列表或字符串的非连续元素

时间:2013-10-02 01:16:31

标签: python string list indexing slice

据我所知,这不是正式不可能的,但通过切片访问列表的任意非顺序元素是否有“技巧”?

例如:

>>> L = range(0,101,10)
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

现在我希望能够做到

a,b = L[2,5]

以便a == 20b == 50

除了两个陈述之外的一种方式是愚蠢的:

a,b = L[2:6:3][:2]

但这根本不会按不规则的间隔进行扩展。

也许使用列表理解使用我想要的索引?

[L[x] for x in [2,5]]

我很想知道这个常见问题的推荐方法。

5 个答案:

答案 0 :(得分:25)

可能与您要查找的内容最接近的是itemgetter(或者对于Python 2文档看起来here):

>>> L = list(range(0, 101, 10))  # works in Python 2 or 3
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
>>> from operator import itemgetter
>>> itemgetter(2, 5)(L)
(20, 50)

答案 1 :(得分:11)

如果您可以使用numpy,则可以这样做:

>>> import numpy
>>> the_list = numpy.array(range(0,101,10))
>>> the_indices = [2,5,7]
>>> the_subset = the_list[the_indices]
>>> print the_subset, type(the_subset)
[20 50 70] <type 'numpy.ndarray'>
>>> print list(the_subset)
[20, 50, 70]

numpy.arraylist非常相似,只是它支持更多操作,例如数学运算以及我们在此处看到的任意索引选择。

答案 2 :(得分:8)

这样的东西?

def select(lst, *indices):
    return (lst[i] for i in indices)

用法:

>>> def select(lst, *indices):
...     return (lst[i] for i in indices)
...
>>> L = range(0,101,10)
>>> a, b = select(L, 2, 5)
>>> a, b
(20, 50)

函数的工作方式是返回一个generator object,它可以与任何类型的Python序列类似地迭代。

正如@justhalf在评论中指出的那样,您可以通过定义函数参数的方式更改调用语法。

def select(lst, indices):
    return (lst[i] for i in indices)

然后你可以用以下方法调用该函数:

select(L, [2, 5])

或您选择的任何列表。

更新:我现在建议使用operator.itemgetter,除非您确实需要生成器的惰性评估功能。请参阅John Y's answer

答案 3 :(得分:3)

为了完整起见,原始问题的方法非常简单。如果L是函数本身,您可能希望将其包装在函数中,或者事先将函数结果赋值给变量,因此不会重复调用它:

[L[x] for x in [2,5]]

当然它也适用于字符串......

["ABCDEF"[x] for x in [2,0,1]]
['C', 'A', 'B']

答案 4 :(得分:1)

其他答案都不适用于multidimensional object切片。恕我直言,这是最通用的解决方案(使用numpy):

numpy.ix_允许您同时在数组的所有维度中选择任意索引。

e.g:

>>> a = np.arange(10).reshape(2, 5) # create an array
>>> a
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
>>> ixgrid = np.ix_([0, 1], [2, 4]) # create the slice-like grid
>>> ixgrid
(array([[0],
       [1]]), array([[2, 4]]))
>>> a[ixgrid]                       # use the grid to slice a
array([[2, 4],
       [7, 9]])