查找列表中较小列表的确切位置(python)

时间:2011-10-27 19:42:30

标签: python list indexing find nested-lists

所以我有一个类似的列表:

list=[10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 9.9, 9.9, 9.9, 10.0, 10.0, 10.0, 10.2, 10.0, 9.9, 9.9, 9.9, 9.9, 10.0, 10.2, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.2, 10.5, 10.9, 10.5, 10.3, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.4, 10.7, 10.3, 10.2, 10.1, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 9.9, 9.9, 10.1, 9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.7, 9.8, 9.8, 9.7, 9.7, 9.7, 9.7, 9.7, 9.7, 9.6, 9.7]

然后我还有一个看起来像这样的子列表:

sublist=[9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8]

现在我需要对这个较小的列表做些什么,我必须找到它在主列表中的位置。 所以在这种情况下,结果应该是这样的:index = 119(我可能会以+/- 1关闭)

我一整天都在尝试这样做......并没有在网上找到任何东西...... 我有一些想法:

1)我在列表中找到子列表的第一项....在这种情况下将是4,所以我检查下一个数字也是正确的然后下一个将是错误的它会发送它在剩余的列表[4:]中找到另一个9.9并再次执行相同的循环...直到找到完全匹配

2)然后另一个想法是以某种方式使用字符串 str(list)[1:-1] .find(str(sublist)[1:-1]),在这种情况下会得到687的答案......

这些想法的问题在于它们似乎很长而且草率,而且我也无法使这些想法发挥作用......

4 个答案:

答案 0 :(得分:3)

怎么样:

l = [10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 9.9, 9.9, 9.9, 10.0, 10.0, 10.0, 10.2, 10.0, 9.9, 9.9, 9.9, 9.9, 10.0, 10.2, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.2, 10.5, 10.9, 10.5, 10.3, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.4, 10.7, 10.3, 10.2, 10.1, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 9.9, 9.9, 10.1, 9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.7, 9.8, 9.8, 9.7, 9.7, 9.7, 9.7, 9.7, 9.7, 9.6, 9.7]
subl = [9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8]
for i in xrange(len(l)-len(subl)):
  if l[i:i+len(subl)] == subl:
    print 'found at pos', i
    break
else:
  print 'not found'

这会打印found at pos 118

P.S。我已重命名变量,以便list不会影响内置函数。

答案 1 :(得分:2)

ind = l.index(subl[0])
for i in xrange(l.count(subl[0])-1):
    if l[ind:ind+len(subl)] == subl:
        print (ind)
        break;
    ind = l.index(subl[0],ind+1)

这是一种有效的方式,只有在知道至少存在subl的第一个值时才进行比较。

答案 2 :(得分:1)

你的第二个想法可能会产生误报:如果子列表是单个值,比如1,而完整列表只有值11,那么它会找到一个匹配项。如果在字符串中添加了前导和尾随分隔符,则可以避免这种情况。

你的第一个想法是最佳解决方案的一半;有一个算法(其名称目前逃脱了我),用于确定你可以“重用”多少子字符串,这样你就不必在完整的字符串中回溯。例如,假设您当前的候选人失败了,因为您发现了一个9.9,您预期为9.8;您不需要重新访问该元素,因为它匹配子字符串的第一个元素。这些可以预先计算,所以你最终只需要在一次通过中走完整个列表。

答案 3 :(得分:1)

idx = next(i for i in range(len(lst)-len(sublst)) if lst[i:i+len(sublist)] == sublst)
# 118