在python中访问列表或字符串的非连续元素
据我所知,这在官方上是不可能的,但通过切片访问列表中任意非顺序元素有“技巧”吗 例如:在python中访问列表或字符串的非连续元素,python,string,list,indexing,slice,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==20和b==50 除了两种说法之外,还有一种说法是愚蠢的: a,b = L[2:6:3][:2] 但这根本不适用于不规则的时间间隔 也许用我想要的索引来理解列表 [L
>>> 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]]
我很想知道针对这个常见问题的建议。如果您可以使用
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
>>>_list=numpy.array(范围(0101,10))
>>>_指数=[2,5,7]
>>>_子集=_列表[_索引]
>>>打印_子集,键入(_子集)
[20 50 70]
>>>打印列表(_子集)
[20, 50, 70]
非常类似于
列表
,只是它支持更多的操作,如数学运算和我们在这里看到的任意索引选择。可能最接近您要查找的是(或查找Python 2文档):
像这样的
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)
该函数的工作方式是返回一个类似于任何类型Python序列的可迭代函数
正如@justhalf在注释中所指出的,可以通过定义函数参数的方式更改调用语法
def select(lst, indices):
return (lst[i] for i in indices)
然后您可以使用以下命令调用函数:
select(L, [2, 5])
或者你选择的任何清单
更新:我现在建议改用
操作符.itemgetter
,除非您确实需要生成器的惰性求值功能。请参阅。为了完整起见,原始问题的方法非常简单。如果L
本身是一个函数,您可能希望将其包装在函数中,或者事先将函数结果赋给一个变量,这样它就不会被重复调用:
[L[x] for x in [2,5]]
当然,它也适用于字符串
["ABCDEF"[x] for x in [2,0,1]]
['C', 'A', 'B']
其他答案都不适用于切片。IMHO这是最通用的解决方案(使用
numpy
):
允许您同时在数组的所有维度中选择任意索引
e、 g:
a,b=L[2],L[5]
?@roippi-这确实让它看起来很简单,但我想将其直接应用于返回列表的函数的输出,而无需调用函数两次或将其重新分配给变量,然后再抓取。我倾向于说,您对列表的理解是最好的。或者,如果您不需要实际的列表,请使用生成器表达式,如Shashank Gupta的回答中所述(尽管如果您只需要一次,您可以将genexp内联,而不是生成一个函数来返回它)。您是否认为将函数定义为select(lst,index)
并将其称为select(L,[2,5])
会更好吗?@只有一半是的,也有可能,我会记下来。@Shashank快速提问。“*index”参数只是“*args”对吗?但是有不同的名字吗?@HalcyonAbrahamRamirez是的,没错。:)但是,这是一个非常古老的答案,我建议使用操作符.itemgetter
,除非需要生成器的惰性求值功能。@justhalf:嗯,itemgetter
与Shashank的答案非常相似,只是已经包含在Python标准库中。这是一个很好的解决方案,但我认为额外的投票是因为它来得稍微早一点。。。我最终选择了一个不需要导入的函数,尽管它主要是将OP封装在函数定义中。@beroe:即使你接受了另一个答案,它仍然会获得更多的新投票,所以早些时候与此无关。我相信我的答案获得更多选票的原因是,有经验的Python程序员通常更喜欢使用itemgetter
,而不是定义一个新函数。一个导入比一个函数定义更短、更简单。我喜欢它作为一种解决方案。(我也投了赞成票;^)对于Python3,第一行将更改为>>L=list(范围(0,101,10))
以执行“相同”操作。是的,太糟糕了,Python没有更好的数组类型数据基本支持,而不需要numpy
,我认为它不是被接受的答案的原因是(a)它有更多的膨胀,(b)它不太一般化。(a) :numpy
是一个巨大的库,这个答案把整个东西都拉了进来。(可能是numpy导入数组中的)(b):numpy
是专门用于数学运算的,因此对于那些关注后端web开发的人来说不太熟悉itemgetter
更接近于“裸”Python,可以接触到更广泛的受众。来自numpy import array
我相信仍然会加载整个numpy包。但你是对的,如果这个列表不用于数学运算,这可能会有点过头。
["ABCDEF"[x] for x in [2,0,1]]
['C', 'A', 'B']
>>> 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]])