我有这个变量:
myList = [
range(27,35),
range(19,27),
range(11,19),
range(92,100),
range(125,133)
]
我想在列表中搜索一个项目(比方说98)并返回包含该项目的列表的索引(在本例中为3)。
我发现了这个:https://stackoverflow.com/a/2206174/788054。这看起来很棒,但是我无法将其调整到列表中,而且生成器让我感到困惑。
答案 0 :(得分: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
生成器/生成器表达式与正常函数/代码之间的区别如下
在我们调用它们之前不会对它们进行评估(延迟评估)。例如,请考虑此列表理解
a = [idx for idx, item in enumerate(myList) if 98 in item]
print a
[3]
立即执行并给出结果。但是,gen exps不是这样的
a = (idx for idx, item in enumerate(myList) if 98 in item)
print(a)
# <generator object <genexpr> at 0x7f599213b3a8>
它返回一个生成器对象。我们必须使用next
协议手动调用它。
他们不会立即执行死刑。例如,假设有多个匹配
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
。
这非常有用,当您需要遍历大量项目或处理大型文件时,您不必将整个列表/文件存储在内存中。您可以简单地遍历内容,处理它们并继续下一个块。
注意:强>
一旦发电机耗尽,它们就无法再次使用。您需要创建一个新的生成器。
您不能在生成器中跳过或向后移动。它只需一步,只需前进迭代器。
生成器最适合迭代。但是,如果要将值列表从生成器转换为列表,则只需使用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]
答案 1 :(得分:1)
[index for index, l in enumerate(myList) if 98 in l]