[英]Accessing non-consecutive elements of a list or string in python
據我所知,這不是正式不可能的,但通過切片訪問列表的任意非順序元素是否有“技巧”?
例如:
>>> 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]]
我很想知道這個常見問題的推薦方法。
可能與您正在尋找的最接近的是itemgetter
(或者在這里查看Python 2文檔):
>>> 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)
如果你可以使用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
非常相似,只是它支持更多操作,例如數學運算以及我們在這里看到的任意索引選擇。
像這樣的東西?
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])
或任何您選擇的清單。
更新:我現在建議使用operator.itemgetter
除非你真的需要生成器的惰性評估功能。 請參閱John Y的回答 。
為了完整起見,原始問題的方法非常簡單。 如果L
是函數本身,您可能希望將其包裝在函數中,或者事先將函數結果賦值給變量,因此不會重復調用它:
[L[x] for x in [2,5]]
當然它也適用於字符串......
["ABCDEF"[x] for x in [2,0,1]]
['C', 'A', 'B']
其他答案都不適用於多維對象切片。 恕我直言這是最通用的解決方案(使用numpy
):
numpy.ix_
允許您同時在數組的所有維度中選擇任意索引。
例如:
>>> 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]])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.