2014-03-27 311 views
1

我有這個變量:嵌套列表中搜索

myList = [ 
    range(27,35), 
    range(19,27), 
    range(11,19), 
    range(92,100), 
    range(125,133) 
] 

我想搜索列表中的項目(可以說98),並返回包含該項目的列表索引(在這種情況下3) 。

我發現這個:https://stackoverflow.com/a/2206174/788054。這看起來很棒,但是我無法適應列表,而生成器會讓我困惑。

回答

1

您可以創建一個生成器表達式這樣並與next功能

next(idx for idx, item in enumerate(myList) if 98 in item) 
# 3 

這可以理解這樣

for idx, item in enumerate(myList): 
    if 98 in item: 
     print idx 

發電機/發電機表達和正常之間的差異獲取下一個值功能/代碼如下

  1. 他們不會被評估,直到我們援引他們(懶惰評估)。例如,考慮這個列表理解

    a = [idx for idx, item in enumerate(myList) if 98 in item] 
    print a 
    [3] 
    

    這立即執行並給出結果。但是,gen gen不是這樣的

    a = (idx for idx, item in enumerate(myList) if 98 in item) 
    print(a) 
    # <generator object <genexpr> at 0x7f599213b3a8> 
    

    它返回一個生成器對象。我們必須用next協議手動調用它。

  2. 它們不會立即執行。例如,假設有多個匹配

    print([idx for idx, item in enumerate([1, 2, 3, 4]) if item % 2]) 
    # [0, 2] 
    

    LC立即返回兩個索引。但是,當我們使用GenExp和next prototcol時,它會產生第一個索引,保留當前的執行上下文並將控制權轉交給調用者。當我們再次調用next時,它將從其剩下的地方恢復執行。

    gen_exp = ((idx for idx, item in enumerate([1, 2, 3, 4]) if item % 2)) 
    print(next(gen_exp)) 
    # 0 
    print(next(gen_exp)) 
    # 2 
    print(next(gen_exp)) 
    # StopIteration 
    

    注:當發電機耗盡他們提出StopIteration

    這非常有用,當您需要遍歷大量項目列表或處理大型文件時,您不必將整個列表/文件存儲在內存中。您可以簡單地迭代內容,處理它們並轉到下一個塊。

注:

  1. 一旦發電機耗盡他們不能再被使用。您需要創建一個新的生成器。

  2. 您不能在發電機中跳過或向後移動。它的一個步驟,只轉發迭代器。

  3. 發電機最適合於迭代。但是,如果要將生成器中的值列表轉換爲列表,則只需使用list函數即可。例如,

    print([idx for idx, item in enumerate([1, 2, 3, 4]) if item % 2]) 
    # [0, 2] 
    gen_exp = ((idx for idx, item in enumerate([1, 2, 3, 4]) if item % 2)) 
    print(list(gen_exp)) 
    # [0, 2] 
    
+0

很透徹,謝謝! – Ryan

1
[index for index, l in enumerate(myList) if 98 in l]