如果找到数字序列,Python拆分列表

时间:2015-09-17 13:06:13

标签: python list

我一直试图找到一个相关的问题,虽然我似乎无法搜索正确的单词,但我发现的是如何检查列表是否包含交集。

基本上,我需要在找到某个数字序列后拆分列表,类似于执行str.split(sequence)[0],而是使用列表。我有工作代码,虽然它看起来效率不高(也不知道如果提出错误是正确的方法),我相信必须有更好的方法来实现它。

对于记录,long_list可能有几百万个值的长度,这就是为什么我认为迭代它们可能不是最好的主意。

long_list = [2,6,4,2,7,98,32,5,15,4,2,6,43,23,95,10,31,5,1,73]
end_marker = [6,43,23,95]
end_marker_len = len(end_marker)

class SuccessfulTruncate(Exception):
    pass
try:
    counter = 0
    for i in range(len(long_list)):
        if long_list[i] == end_marker[counter]:
            counter += 1
        else:
            counter = 0
        if counter == end_marker_len:
            raise SuccessfulTruncate()
except SuccessfulTruncate:
    long_list = long_list[:2 + i - end_marker_len]
else:
    raise IndexError('sequence not found')

>>> long_list
[2,6,4,2,7,98,32,5,15,4,2]

好的,用100万个值的大清单计算几个答案(标记非常接近结束):

Tim: 3.55 seconds
Mine: 2.7 seconds
Dan: 0.55 seconds
Andrey: 0.28 seconds
Kasramvd: still executing :P

4 个答案:

答案 0 :(得分:3)

  

我有工作代码,虽然它看起来效率不高(也不知道如果提出错误是正确的方法),我确信必须有更好的方法做到这一点。

我在评论中对异常提出进行了评论

  

而不是引发异常并在同一个try /中捕获它,除了你可以省略try / except并执行if counter == end_marker_len: long_list = long_list[:2 + i - end_marker_len]。成功不是适合例外名称的词。例外用于表示某些内容失败

无论如何,这是一个更短的方式:

>>> long_list = [2,6,4,2,7,98,32,5,15,4,2,6,43,23,95,10,31,5,1,73]
>>> end_marker = [6,43,23,95]
>>> index = [i for i in range(len(long_list)) if long_list[i:i+len(end_marker)] == end_marker][0]
>>> long_list[:index]
[2, 6, 4, 2, 7, 98, 32, 5, 15, 4, 2]

this帖子

启发的列表理解

答案 1 :(得分:3)

作为一种更加pythonic的方式而不是多次切片,你可以在列表理解中使用itertools.islice

>>> from itertools import islice
>>> M,N=len(long_list),len(end_maker)
>>> long_list[:next((i for i in range(0,M) if list(islice(long_list,i,i+N))==end_marker),0)]
[2, 6, 4, 2, 7, 98, 32, 5, 15, 4, 2]

请注意,由于next函数的默认值为0,如果找不到任何匹配项,它将返回整个long_list

答案 2 :(得分:1)

如果值的范围有限,比如以字节为单位(这也可以适应更大的类型),那么为什么不对列表进行编码,以便可以使用字符串方法find

long_list = [2,6,4,2,7,98,32,5,15,4,2,6,43,23,95,10,31,5,1,73]
end_marker = [6,43,23,95]

import struct

long_list_p = struct.pack('B'*len(long_list), *long_list)
end_marker_p = struct.pack('B'*len(end_marker), *end_marker)

print long_list[:long_list_p.find(end_marker_p)]

打印:

[2, 6, 4, 2, 7, 98, 32, 5, 15, 4, 2]

我尝试使用bytes,但他们所使用的查找方法并不起作用:

print long_list[:bytes(long_list).find(bytes(end_marker))]

答案 3 :(得分:1)

在我使用index方法的解决方案中使用方法:

input = [2,6,4,2,7,98,32,5,15,4,2,6,43,23,95,10,31,5,1,73]
brk = [6,43,23,95]
brk_len = len(brk)
brk_idx = 0
brk_offset = brk_idx + brk_len

try:
    while input[brk_idx:brk_offset] != brk:
        brk_idx = input.index(brk[0], brk_idx + 1)
        brk_offset = brk_idx + brk_len
except ValueError: 
    print("Not found")
else:
    print(input[:brk_idx])