python實現複雜範圍重組

2021-05-28 17:58:47 字數 4376 閱讀 3599

為達到高速的全規則匹配(一條資料要和當前所有規則進行匹配,而不是匹配即跳出),需要乙個二叉判斷樹,二叉判斷樹的輸入要求乙個有序的、互斥的判斷閾值序列。但是,顯示中的業務規則絕大多數都是交叉的,比如企業業務規則,同乙個/組ip可能會和多個/組ip有互動,因此要對其建立多條規則,而且組與組之間的範圍還非常可能是疊加的。因此,需要程式自動的差分判斷範圍,以供判斷樹的生成。

#!/usr/bin/env python

#coding = utf-8

'''author: yang xu

e-mail: [email protected]

'''class _segment(object):

__slots__ = ('value', 'ishead', 'istail')

def __init__(self, value, ishead=false, istail=false):

self.value = value

self.ishead = ishead

self.istail = istail

def __str__(self):

h = 'h' if self.ishead else ''

t = 't' if self.istail else ''

return '<%s%s%s>'%(h, self.value, t)

__repr__ = __str__

class span(object):

__slots__ = ('start', 'end', 'srcs')

def __init__(self, start, end, srcs):

self.start = start

self.end = end

self.srcs = srcs

def __str__(self):

return ''%(self.start, self.end, str(self.srcs))

__repr__ = __str__

def _seglist(sequence):

tmp_set = set()

for span in sequence:

start = span[0]

end = span[1]

tmp_set.add(start)

tmp_set.add(end)

tmp_set = sorted(list(tmp_set))

header = set([span[0] for span in sequence])

tailer = set([span[1] for span in sequence])

seg_list =

for item in tmp_set:

ishead = item in header

istail = item in tailer

segment = _segment(item, ishead, istail)

return seg_list

def _spanlist(seg_list):

span_list =

for seg in seg_list:

# add value-1 before header

if seg.ishead:

if span_list:

# add value

# add value if ishead & istail

if seg.ishead and seg.istail:

# add value+1 after tailer

if seg.istail:

return span_list

def _filter(span_list, sequence,

getstart=lambda item: item[0],

getend=lambda item: item[1],

gettag = lambda item: item

):def belongs(span, sequence):

s = span[0]

t = span[1]

tag_list =

for item in sequence:

_s = getstart(item)

_t = getend(item)

tag = gettag(item)

if _s<=s<=_t and _s<=t<=_t:

return tag_list

taglists = map(lambda span: belongs(span, sequence), span_list)

return_list =

for index in xrange(len(taglists)):

tags = taglists[index]

span = span_list[index]

if tags:

return return_list

def split(sequence,

getstart=lambda item: item[0],

getend=lambda item: item[1],

gettag = lambda item: item

):sequence_list = [(getstart(obj), getend(obj)) for obj in sequence]

seg_list = _seglist(sequence_list)

span_list = _spanlist(seg_list)

starts = span_list[0::2]

ends = span_list[1::2]

return_list =

for index in xrange(len(ends)):

start = starts[index]

end = ends[index]

if start > end: continue

return_list = _filter(

return_list, sequence,

getstart = getstart,

getend = getend,

gettag=gettag

)return return_list

if __name__ == '__main__':

ls = [

[-1, 10],

[3, 7],

[10, 15],

[12, 20],

[22, 22],

[24, 30]

]s = split(ls)

print

for i in s:

print i

class o(object):

def __init__(self, id, s, e):

self.tag = id

self.start = s

self.end = e

def __str__(self):

return '<%s-%s>'%(self.start, self.end)

__repr__ = __str__

seq =

count = 1

for span in ls:

count += 1

seq.sort(cmp = lambda x, y: cmp(x.start, y.start))

s = split(seq,

getstart=lambda item: item.start,

getend=lambda item: item.end,

gettag = lambda item: item#.tag

)print

for i in s:

print i

# result:

# # # # # # # # # #

# ]>

# , <3-7>]>

# ]>

# , <10-15>]>

# ]>

# , <12-20>]>

# ]>

# ]>

# ]>

給定乙個 部分重疊、完全重疊、連續、間斷的序列,上述**會將其拆分為更細的span,然後返回拆分好後的span及其所屬的原始序列。載體為span物件。

同時,輸入序列可以是簡單的二元組,分為表示start和end,也可以是乙個複雜物件,此時需要定義獲取物件屬性對應到start和end的方法getstart和getend。

gettag引數用來決定返回所屬原始序列時的值,預設是輸入時物件本身。

python函式範圍 Python函式範圍

我有乙個關於 python函式範圍的問題.我已經包含了乙個示例,說明了我遇到的問題.fun0重新定義了varible c列表中的第乙個條目.這個變化反映在fun0之外,即使我沒有從fun0返回任何值.fun1完全重新定義變數c,但更改不會在fun1之外反映出來.同樣,fun2重新定義了c,並且更改不...

TCP資料報重組實現分析

參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料段第一位元組的序號 資...

TCP資料報重組實現分析

tcp重組資料報分析 參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料...