2014-03-27 263 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]