【问题标题】:Python: Return all Indices of every occurrence of a Sub List within a Main List [duplicate]Python:返回主列表中每次出现的子列表的所有索引[重复]
【发布时间】:2016-10-12 00:28:15
【问题描述】:

我有一个主列表和一个子列表,我想定位在主列表中找到的每个子列表的索引,在本示例中,我希望返回以下索引列表。

>>> main_list = [1,2,3,4,4,4,1,2,3,4,4,4]
>>> sub_list = [4,4,4]

>>> function(main_list, sub_list)
>>> [3,9]

理想情况下,该函数还应该忽略 sub_list 的片段,在这种情况下 [4,4] 将被忽略。另外,我希望元素都是个位数的整数。为清楚起见,这是第二个示例:

>>> main_list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
>>> sub_list = [5,5,5,5,5]

>>> function(main_list, sub_list)
>>> [3,11,19]

【问题讨论】:

  • main_list = [4, 4, 4]sub_list = [4, 4] 会发生什么?
  • 您的用例是否总是包含单个数字元素?因为这样你就可以制作一个简单的基于正则表达式的解决方案。
  • @MosesKoledoye 我认为这会返回 [0, 1]
  • 根据您的数据,您可能会从像 Boyer-Moore 或 Knuth-Morris-Pratt 这样的 string search algorithm 中获得一些好处,特别是如果 sub_list 可能很长或有很多几乎匹配。
  • 一个幼稚的解决方案[i for i in range(len(main_list) - len(sub_list) + 1) if main_list[i:i+len(sub_list)] == sub_list]

标签: python list indexing indices sublist


【解决方案1】:

也许使用字符串是要走的路?

import re
original = ''.join([str(x) for x in main_list])
matching = ''.join([str(x) for x in sub_list])
starts = [match.start() for match in re.finditer(re.escape(matching), original)]

这个唯一的问题是它不计入重叠值

【讨论】:

  • Padraic Cunningham 在我认为问题的 cmets 中提供的答案要好得多,并且确实考虑了重叠值。
【解决方案2】:

您应该能够使用 for 循环,然后将其拆分为您的子列表列表的长度,遍历并在您的主列表中查找子列表。试试这个:

main_list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
sub_list = [5,5,5,5,5]

indices = []
for i in range(0, len(main_list)-len(sub_list)+1):
    temp_array = main_list[i:i+len(sub_list)]
    if temp_array == sub_list:
        indices.append(i)

print indices

【讨论】:

    【解决方案3】:

    这是一种递归方式:

    list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
    
    def seq(array):  # get generator on the list
        for i in range(0,len(array)):
            yield i
    
    sq = seq(list) # get the index generator
    
    
    
    def find_consecutive_runs(array): # Let's use generator - we are not passing index
    
        i=next(sq) # get the index from generator
    
        if len(array) > 5: # or 3, or 4, or whatever - get slice and proceed
    
            arr = array[:5] # slice 5 elements
    
            if all(x==arr[0] for x in arr): # all list elements are identical
                print i # we found the index - let's print it
    
            find_consecutive_runs(array[1:len(array)]) # proceed with recursion
    
    find_consecutive_runs(list) # the actual call 
    

    【讨论】:

      猜你喜欢
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-26
      • 2020-11-22
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      相关资源
      最近更新 更多