2017-06-14 298 views
2

請有人可以幫助我獲取嵌套列表中的項目索引,其中使用Python 2.7滿足特定條件?我知道在StackOverflow上有類似的問題,但我似乎無法找到處理「嵌套」列表的好例子。Python - 從滿足條件的嵌套列表中獲取索引

我有數據的列表,這是長行數十萬,在下面的格式:

data =[ 
["","","","28.04.2015 09:34:38",1.52411,1.52428,17], 
["","","","28.04.2015 09:34:40",1.52415,1.52433,18], 
["","","","28.04.2015 09:34:42",1.52425,1.52444,19], 
["","","","28.04.2015 09:34:44",1.52417,1.52435,18], 
["","","","28.04.2015 09:34:46",1.52421,1.52440,19], 
["","","","28.04.2015 09:34:48",1.52426,1.52446,20], 
["","","","28.04.2015 09:34:50",1.52429,1.52444,15], 
["","","","28.04.2015 09:34:58",1.52423,1.52441,18], 
["","","","28.04.2015 09:35:00",1.52416,1.52434,18], 
["","","","28.04.2015 09:35:02",1.52416,1.52433,17], 
["","","","28.04.2015 09:35:04",1.52416,1.52434,18], 
["","","","28.04.2015 09:35:06",1.52406,1.52422,16], 
["","","","28.04.2015 09:35:10",1.52406,1.52421,15], 
["","","","28.04.2015 09:35:14",1.52427,1.52444,17], 
["","","","28.04.2015 09:35:16",1.52424,1.52443,19], 
["","","","28.04.2015 09:35:18",1.52434,1.52453,19], 
["","","","28.04.2015 09:35:20",1.52434,1.52451,17], 
["","","","28.04.2015 09:35:22",1.52438,1.52456,18], 
["","","","28.04.2015 09:35:24",1.52432,1.52451,19], 
["","","","28.04.2015 09:35:28",1.52445,1.52464,19], 
["","","","28.04.2015 09:35:34",1.52435,1.52451,16], 
["","","","28.04.2015 09:35:36",1.52432,1.52449,17], 
["","","","28.04.2015 09:35:38",1.52429,1.52448,19]] 

對於每一行我想要的數據「5列」比較(第一關口十進制數字)設置爲某個值(以1.52440爲例),並返回數據大於我的特定值的第一行的索引。

我已經做了這種使用for-row-in-data類型循環的'傳統'方式的代碼,但是我希望儘可能使用更好(更快)的方法,而且似乎無法產生預期的結果。

,我已經取得迄今已是相當差的嘗試:

pricedata = [n[4] for n in data] 
myindex = (x for x in enumerate(pricedata) if x > 1.5440).next() 

第一行中提取價格數據山坳作爲一個新的列表。我不確定這是否真的有必要,但是由於我對列表解析的理解很差,我試圖將事情分解成我理解的步驟。

我真的不明白第二行正在做什麼,但它似乎返回(0,1.52411) - 列表中的第一項 - 無論我輸入什麼比較值。

我也曾嘗試:

myindex = [x for x in enumerate(pricedata) if x > 1.5440][0] 

,它似乎產生相同的結果。

我認爲理解是說:

「讓價的列表供您在列表的索引,價格看,如果價格任您正在看的,比大於每個價格1.5440「,但似乎我錯了!

請有人指出我的方式的錯誤,並幫助我嗎?感謝您的幫助!

+0

列表似乎並沒有進行排序 – depperm

回答

4

問題是,你要比較一個元組的浮動,因爲索引和項目的收益enumerate元組,然而,元組被認爲更大比花車在Python 2:

>>>() > 4. 
True 

因此,由enumerate生成的第一個元組總是產生一個匹配。


爲了解決這個問題,你應該改爲解壓元組第一,並且使用next從你的產生表達返回第一個匹配指數:

next(i for i, x in enumerate(data) if x[4] > 1.52415) 
+0

也許可以通過將默認值傳遞給next來管理「不匹配的行」情況。 –

+0

@Jérôme取決於。如果他們想通過傳遞默認值,他們可以消除錯誤,但是,有時需要錯誤。 –

+0

你說得對。但是,接下來介紹時可能會提及StopIteration。但我同意使用默認值不必是自動的。 –

0

這可以通過分割成enumrator索引和值來實現:當在列表中沒有項謂詞匹配被執行

try: 
    first_index = (index for index, data in enumerate(data) 
        if data[4] > 1.52415).next() 
except StopIteration: 
    first_index = -1 

StopIteration部。

+0

使用next((發電機),無),您將提供下一個默認值,您不必捕獲StopIteration。 –

+0

我的意思是下一個((發生器),-1)在你的情況。 –

2

你濫用enumerate。它迭代你提供的序列/迭代器,併產生索引/值對。

試試這個:

myindex = next(index for index, row in enumerate(data) if row[5] > 1.52440) 

(i for i, row in enumerate(data) if row[4] > 1.52440) 

部分是發電機,它產生滿足條件的行的索引。

next遍歷此生成器,直到返回第一行。

因爲他使用的是生成器而不是中介列表,所以不必通過整個列表。在找到與條件匹配的第一行後,搜索停止。當表格中有許多行時,這很重要。

請注意,如果找不到匹配的行,您將得到一個StopIteration異常。如果你想在這種情況下(如None)特定的值,你可以將它作爲第二個參數next

myindex = next((index for index, row in enumerate(data) if row[5] > 1.52440), None) 
0
data=[[0,0,0,0,0,0],[1,0,0,0,0,0],[0,0,0,0,0,0],[1,0,0,0,0,0],[0,0,0,0,0,0],[1,0,0,0,0,0],[0,0,0,0,0,0]] 
for index, value in enumerate(data): 
    if value[0] > 0: 
     print(index) 
     break 
+0

在找到第一個好行之後,您至少可以休息一下。 –

+0

是的,我忘了op只問第一場比賽。謝謝 –

+0

雖然這段代碼可能會回答這個問題,但提供關於爲什麼和/或代碼如何回答這個問題的附加上下文會提高它的長期價值。 –