我一直试图找到一个相关的问题,虽然我似乎无法搜索正确的单词,但我发现的是如何检查列表是否包含交集。
基本上,我需要在找到某个数字序列后拆分列表,类似于执行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
答案 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])