algorithm - Digram list manipulation with Python -
i'd make additions/replacements digram list looks similar this:
[[a,b][b,c][c,d][d,c][c,b][b,a]] if list flattened, outcome be: ´´[a,b,c,d,c,b,a]´´ describing structure, not issue.
note there 2 items on digram , each of 2 items on digram precedes next , previous digram items, except of first , last digram, terminating item occurs once. see item ´´a´´.
my question how can replace digrams list, next example results on comment part fulfill:
replace([['d','d']], 1, ['a', 0]) # should return: [['d', 'd']] replace([['d',1]], 1, ['a', 0]) # should return: [['d', 'a'], ['a', 0]] replace([[1,'d']], 1, ['a', 0]) # should return: [['a', 0], [0, 'd']] replace([[1,'d'],['d', 1]], 1, ['a', 0]) # should return: [['a', 0], [0, 'd'], ['d', 'a'], ['a', 0]] replace([['d',1],[1,'d']], 1, ['a', 0]) # should return: [['d','a'], ['a', 0], [0, 'd']] replace([[1,1]], 1, ['a', 0]) # should return: [['a', 0], [0, 'a'], ['a', 0]] replace([[1,1],[1,1]], 1, ['a', 0]) # should return: [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]] i have tried next approach, has issues. part under ´´j == 1´´ has special cases doesnt work.
def replace(t, a, b): """ 1. argument target list 2. argument index value used on replacement 3. argument digram inserted """ # copy possibly not needed, im not sure t1 = t[:] i, x in enumerate(t1): j, y in enumerate(x): # if there digram match, lets make replacement / addition if y == a: if j == 0: c = t1[i:] del t1[i:] t1 += [b] + c c[0][0] = b[1] if j == 1: c = t1[i:] del t1[i:] t1 += c + [b] c[len(c)-1][1] = b[0] #c[0][1] = b[0] #t1 += c print (t, t1) can suggest tips improve function or have alternative ways task?
addition
this enchanged version of function, provides right answers, still "annoying" part of or whole approach optimized. question , topic changed more code optimization area:
def replace(t, a, b): """ 1. argument target list 2. argument index value used on replacement 3. argument digram inserted """ l = len(t) = 0 while < l: j, y in enumerate(t[i]): # if there digram match, lets make replacement / addition if y == a: if j == 0: c = t[i:] del t[i:] t += [b] + c c[0][0] = b[1] # increase both index , length # practically jumps on inserted digram next 1 += 1 l += 1 elif j == 1: c = t[i:] del t[i:] # annoying part of algorithm... if len(c) > 1 , c[1][0] == a: t += c else: t += c + [b] c[-1][1] = b[0] t[i][1] = b[0] += 1 return t i provide test function test inputs , outputs:
def test(ins, outs): try: assert ins == outs return (true, 'was', outs) except: return (false, 'was', ins, 'should be', outs) i, result in enumerate( [result result in [ [replace([['d','d']], 1, ['a', 0]), [['d', 'd']]], [replace([['d',1]], 1, ['a', 0]), [['d', 'a'], ['a', 0]]], [replace([[1,'d']], 1, ['a', 0]), [['a', 0], [0, 'd']]], [replace([[1,'d'],['d', 1]], 1, ['a', 0]), [['a', 0], [0, 'd'], ['d', 'a'], ['a', 0]]], [replace([['d',1],[1,'d']], 1, ['a', 0]), [['d','a'], ['a', 0], [0, 'd']]], [replace([[1,1]], 1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0]]], [replace([[1,1],[1,1]], 1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]]], [replace([['d',1],[1,1]], 1, ['a', 0]), [['d', 'a'], ['a', 0], [0, 'a'], ['a', 0]]], [replace([[1,1],[1,'d']], 1, ['a', 0]), [['a', 0], [0, 'a'], ['a', 0], [0, 'd']]] ]]): print (i+1, test(*result))
this approach. explanation below.
def replace(t, a, b): # flatten list t = [elem sub in t elem in sub] replaced = [] # iterate elements of flattened list # let elements not match in , replace ones # not match elements of b elem in t: if elem == a: # element matches, replace b replaced.extend(b) else: # element not, add replaced.append(elem) # break replaced, flattened list groups of 2 elements return [replaced[x:x+2] x in range(len(replaced)-1)] you start list of lists. first, can flatten that.
[[1,'d'],['d', 1]] becomes [1,'d','d', 1] now can loop through flattened list , anywhere find match on a can extend our replaced list contents of b. if element not match a append replaced. end with:
['a', 0, 'd', 'd', 'a', 0] now want take of these in groups of 2, moving our index 1 @ time.
[['a', 0] ...] [['a', 0], [0, 'd'], ...] [['a', 0], [0, 'd'], ['d', 'd'], ...] if data substantially longer examples , in need of performance improvements, flattening of list removed , flatten value in t nested loop make single pass through t.
edit
def replace(t, a, b): t = [elem sub in t elem in sub] inner_a_matches_removed = [] i, elem in enumerate(t): if not % 2 or elem != a: inner_a_matches_removed.append(elem) continue if < len(t) - 1 , t[i+1] == a: continue inner_a_matches_removed.append(elem) replaced = [] elem in inner_a_matches_removed: if elem == a: replaced.extend(b) else: replaced.append(elem) return [replaced[x:x+2] x in range(len(replaced)-1)] and here addition testing:
args_groups = [ ([['d','d']], 1, ['a', 0]), ([['d',1]], 1, ['a', 0]), ([[1,'d']], 1, ['a', 0]), ([[1,'d'],['d', 1]], 1, ['a', 0]), ([['d',1],[1,'d']], 1, ['a', 0]), ([[1,1]], 1, ['a', 0]), ([[1,1],[1,1]], 1, ['a', 0]), ] args in args_groups: print "replace({}) => {}".format(", ".join(map(str, args)), replace(*args)) which outputs:
replace([['d', 'd']], 1, ['a', 0]) => [['d', 'd']] replace([['d', 1]], 1, ['a', 0]) => [['d', 'a'], ['a', 0]] replace([[1, 'd']], 1, ['a', 0]) => [['a', 0], [0, 'd']] replace([[1, 'd'], ['d', 1]], 1, ['a', 0]) => [['a', 0], [0, 'd'], ['d', 'd'], ['d', 'a'], ['a', 0]] replace([['d', 1], [1, 'd']], 1, ['a', 0]) => [['d', 'a'], ['a', 0], [0, 'd']] replace([[1, 1]], 1, ['a', 0]) => [['a', 0], [0, 'a'], ['a', 0]] replace([[1, 1], [1, 1]], 1, ['a', 0]) => [['a', 0], [0, 'a'], ['a', 0], [0, 'a'], ['a', 0]] i guess still don't understand case #4, seem have solved great!
here modified code:
def replace(t, a, b): # flatten list t1 = [] l = len(t)-1 items in [t[i][0:(1 if i>-1 , i<l else 2)] in range(0,l+1)]: t1.extend(items) replaced = [] # iterate elements of flattened list # let elements not match in , replace ones # not match elements of b elem in t1: if elem == a: # element matches, replace b replaced.extend(b) else: # element not, add replaced.append(elem) # break replaced, flattened list groups of 2 elements return [replaced[x:x+2] x in range(len(replaced)-1)]
Comments
Post a Comment