I have a list like this:
seq = [-2,3,-2,3,5,3,7,1,4,-5,1,4,-5,1,4,-5]
I want to get all the sequential recurrences and where it happens, I feel the way I'm doing its too brute force and in reality I want this for several lists each with length of about 300.
dic = {}
for p1 in range(len(seq)):
for p2 in range(p1+1,len(seq)):
dic.setdefault(tuple(seq[p1:p2]), []).append((p1,p2))
which results in all unique sequences of numbers as keys and their positions as values, for example:
#-2,3: [(0,2),(2,4)]
But also results in a lot of entries that occur only once that don't interest me, I'm 'cleaning' these after by taking only values that have more than 1 entry:
def clean(dic):
cleandic = {}
for key, value in dic.items():
if len(value) > 1:
cleandic.setdefault(key,value)
return cleandic
cleandic = clean(dic)
Now for the last step I'm trying to get rid of the occurrences that happens inside the bigger ones, so I sorted the dict by reverse len of keys (bigger keys comes first), for example:
#(1,4,-5,1,4,-5) : ([7,13),(10,16)]
#...
#(1,4,-5) : [(7,10),(10,13)]
The best I came up with to take out the small ones:
sorteddic = dict(sorted(cleandic.items(), key=lambda item: len(item[0]), reverse=True))
onlybigs = {}
while len(sorteddic) > 0:
for key1, values1 in sorteddic.items():
for key2, values2 in sorteddic.copy().items():
if len(key2) == len(key1):
continue
for value1 in values1: #ex: (7,13)
for value2 in values2: #ex: (7,10)
if value2[0] >= value1[0] and value2[1] <= value1[1]:
sorteddic[key2].pop(sorteddic[key2].index(value2))
onlybigs.setdefault(key1, sorteddic.pop(key1))
break
#and a second clean in the end
readydic = clean(onlybigs)
This last step especially is taking too long because it compares each value for each key and my guess is the whole process can be done more efficiently somehow.
Any insights?
3-2
in yourseq
list. Is this a subtraction, or are you missing a comma? \$\endgroup\$readydict
have lost indexes for the most items{(1, 4, -5, 1, 4): [(7, 12), (10, 15)], (1, 4, -5, 1): [], (4, -5, 1, 4): [], (1, 4, -5): [], (4, -5, 1): [], (-5, 1, 4): [], (-2, 3): [(0, 2), (2, 4)], (1, 4): [(13, 15)], (4, -5): [], (-5, 1): [], (-2,): [], (3,): [(5, 6)], (1,): [], (4,): [], (-5,): []}
<-- empty lists. Is it not working as expected yet? \$\endgroup\$cleandic = {} for key, value in dic.items(): if len(value) > 1: cleandic.setdefault(key,value)
again at the end \$\endgroup\$readydic
, notdic
at the end. Please fix and update your code \$\endgroup\$