据我所知,这不是正式不可能的,但通过切片访问列表的任意非顺序元素是否有“技巧”?
例如:
>>> L = range(0,101,10)
>>> L
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
现在我希望能够做到
a,b = L[2,5]
以便a == 20
和b == 50
除了两个陈述之外的一种方式是愚蠢的:
a,b = L[2:6:3][:2]
但这根本不会按不规则的间隔进行扩展。
也许使用列表理解使用我想要的索引?
[L[x] for x in [2,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.array
与list
非常相似,只是它支持更多操作,例如数学运算以及我们在此处看到的任意索引选择。
答案 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]])