在列表

时间:2015-06-05 08:17:50

标签: python list nested-lists

尝试使用元素查找子列表的索引。我不确定如何准确指出问题(这可能是我在手册中忽略它的原因),但我的问题是:

list1 = [[1,2],[3,4],[7,8,9]]

我想在list1中找到第一个出现7的子列表(在这种情况下,索引是2,但是lll可能非常长)。 (情况是每个数字只出现在1个子列表中 - 或者根本不出现。这些只是整数列表) 即像

这样的函数
spam = My_find(list1, 7)

会给垃圾邮件= 2 我可以尝试循环来制作布尔索引

[7 in x for x in lll]

然后.index找到'true' - (根据Most efficient way to get indexposition of a sublist in a nested list) 然而,确实必须构建一个新的布尔列表是非常低效的..

我的代码开始于list1相对较小,但它不断积累(最终将有大约100个数字排列在list1的大约5000个子列表中

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

  

我可以尝试循环来制作布尔索引

[7 in x for x in lll]
  

然后.index找到'true'...但是肯定要建立一个新的布尔列表是非常低效的

你离这儿很近。

首先,要避免构建列表,只需使用[]替换(),即可使用生成器表达式而不是列表推导。

sevens = (7 in x for x in lll)

但是当你有一个任意的可迭代而不是列表时,你如何做.index的等效?您可以使用enumerate将每个值与其索引相关联,然后只使用filterdropwhile或其他生成器表达式过滤掉非七位数,然后next将为您提供第一个True的索引和值。

例如:

indexed_sevens = enumerate(sevens)
seven_indexes = (index for index, value in indexed_sevens if value)
first_seven_index = next(seven_indexes)

如果你愿意,你当然可以把所有这些都折叠成一个大表达。

而且,如果你考虑一下,你根本不需要那个初始表达;你可以在后面的过滤步骤中做到这一点:

first_seven_index = next(index for index, value in enumerate(lll) if 7 in value)

当然,如果没有sevens,这会引发StopIteration异常而不是ValueError表达式,但是,它会与原始代码完全相同,但不构建列表,并且在第一场比赛后没有继续测试值。