2014-01-21 93 views
3

我有一個看起來像這樣的列表:查找元素的索引子子列表

a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]] 

即:N子列表(只有兩個在這裏)和M子子列表中的每個子-list(在這個例子中是五個)。每個元素/子子列表由兩個浮點組成。

我需要找到給定元素的索引,比如說[0.0185, 6.75]。在這種情況下,結果應該是:[1, 3]

我不能只應用.index()運算符a因爲元素是在一個子列表中,因爲我不知道先驗哪一個是我不能循環通過應用子列表該運算符,因爲如果找不到該元素將導致錯誤。


添加

我試圖通過zhangxaochen ANS DSM在一個更大的陣列的答案(16分列表和70分分表),看看哪一個是速度更快,這是什麼我得到了:

DSM: 4.31537628174e-05 
zhangxaochen: 0.00113296508789 

由於帝斯曼的答案是~26倍,所以我選擇了那個。多謝你們!

+0

當你寫「只有兩個在這裏」,這是否意味着,在現實中,將有超過兩個? –

+0

@Gabriel對於嵌套列表,你如何期望返回索引? – thefourtheye

+0

@thefourtheye沒有更多_nsted_子列表,但其中更多(即:而不是2個子列表,40;而不是5個子子列表,60)也許我表達自己很差,對不起。 – Gabriel

回答

2

一種方法是使用nextenumerate

>>> a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]] 
>>> search_for = [0.0185, 6.75] 
>>> print next(((i,j) for i,x in enumerate(a) for j,y in enumerate(x) 
...    if y == search_for), None) 
(1, 3) 
>>> search_for = [0.0185, 99] 
>>> print next(((i,j) for i,x in enumerate(a) for j,y in enumerate(x) 
...    if y == search_for), None) 
None 

但由於測試花車的平等可能過於敏感,你可能要替換y == search_for與一個is_close(y, search_for)功能,它允許一些容錯的錯誤。使用is in.index的方法無法真正處理該問題。

+0

不幸的是,OP剛剛評論說這些列表可以更深入地嵌套。 –

+0

不,這些列表不會嵌套得更深。我說可以有多個子列表和子子列表(這些子子列表內部甚至是最後一個元素),但是不能相互嵌套,只是它們的數量會增加。 – Gabriel

0

在致電.index()之前使用in進行會員測試。

def find(lst, needle): 
    for i, sublist in enumerate(lst): 
     if needle in sublist: 
      return [i, sublist.index(needle)] 

a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]] 
element = [0.0185, 6.75] 

print(find(a, element)) 

結果:

[1, 3] 
+0

'in'和'index',它們都是'O(N)' – thefourtheye

+0

@thefourtheye這是真的......有更快的方法嗎?如果數據沒有排序或其他結構化,你必須閱讀每個元素,直到你找到你要找的那個,不是嗎? – senshin

+0

@thefourtheye但它們都是內置方法,這意味着它們比python循環更快地遍歷列表。不過確實'senshin'可以使用'sublist.find(needle)'並且避免額外的迭代。或'try'塊內的'sublist.index(needle)'。 – Bakuriu

1

使用next和發電機的表達:

search = [0.0185, 6.75] 

gen = ((ix,iy) for ix,outer in enumerate(a) for iy,inner in enumerate(outer) if inner == search) 

next(gen,'not found') 
Out[27]: (1, 3) 

如果發電機沒有找到結果筋疲力盡,next返回第二個參數(在這種情況下'not found',使用任何你想使用)

如果嵌套列表比較上面會搞亂你,那是語法上等同於:

for ix,outer in enumerate(a): 
    for iy,inner in enumerate(outer): 
     if inner == search: 
      yield (ix,iy) 
2

我想使用numpy做到這一點:

In [93]: from numpy import * 
    ...: a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]] 
    ...: a=np.asarray(a) 
    ...: needle=[0.0185, 6.75] 
    ...: idx=nonzero(all(a==needle, axis=-1)) 
    ...: asarray(idx)[:,0] 
    ...: 
Out[93]: array([1, 3]) 

我refered這些職位:

Python/NumPy first occurrence of subarray

https://github.com/numpy/numpy/issues/2269

通過這種方式,可以處理深度嵌套箱子,例如a=[[[[your data...],[...]]]]是4級嵌套,預期產出指數爲(0,1,3)現在:

In [95]: from numpy import * 
    ...: a = [[[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]] 
    ...: a=np.asarray(a) 
    ...: needle=[0.0185, 6.75] 
    ...: idx=nonzero(all(a==needle, axis=-1)) 
    ...: asarray(idx)[:,0] 
Out[95]: array([0, 1, 3])