comparing and replacing the elements of a nested list
我有一个清单,是:
1 2 3 4 5 6 | mylist = { 'a': [(-1,-1), (0.2,0.4)] 'b': [(0.3,1.0), (-1,-1)] 'c': [(-1,-1), (-1,-1)] 'd': [(0.15,0.35), (0.05,0.15)] } |
我必须得到如下输出:
1 2 3 4 5 6 | mylist = { 'a': [(0.3, 0.35), (0.2,0.4)] 'b': [(0.3,0.35), (0.05,0.15)] 'c': [(0.15,0.35), (0.05,0.15)] 'd': [(0.15,0.35), (0.05,0.15)] } |
上面的列表在我打印的时候是这样的,
1 2 3 4 | mylist = [ ('a', [ (-1, -1), (0.2, 0.4) ] ), ('b', [ (0.3, 1.0), (-1, -1) ] ), ('c', [ (-1, -1), (-1, -1) ] ), ('d', [ (0.15, 0.35), (0.05, 0.15) ] ) ] |
现在算法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1st iteration: Compare a[0] and b[0] ie (-1, -1) and (0.3, 1.0). Here replace (-1, -1) by (0.3, 1.0). Rule: (-1, -1) is considered as empty or not in use so it gets replaced while comparison. Similarly, compare a[1] and b[1] ie (0.2, 0.4) and (-1, -1). Here keep the same value as b[1] is empty so no change. Hence the new elements of 'a' are (0.3, 1.0), (0.2, 0.4). Rule: if comparing with empty one then keep the same values. 2nd iteration: Compare new values of a[0] and c[0] ie (0.3, 1.0) and (-1, -1). Here again no change. Similarly, compare new values of a[1] and c[1] ie (0.2, 0.4) and (-1, -1). Here also no change. Now the new elements of 'a' are (0.3, 1.0), (0.2, 0.4). |
这个过程进行到"a"与列表中的最后一个元素进行比较,直到"d"为止。然后轮到"b",同样的事情将在"b"和"c"之间继续,然后是"b"和"d"等。
比较两个实际范围(0.1,0.3)和(0.5,1.0)时的其他规则。
假设两个范围完全重叠,如(0.1,0.8)和(0.3,0.9),那么,应该取它们之间的共同点,即(0.3,0.8)。
如果它们没有像(0.1,0.4)和(0.5,0.9)那样重叠,那么,它应该选择自己的(0.1,0.4)。
如果它们部分重叠,那么它们之间也有共同点。如(0.4,1.0)和(0.8,1.5),则应选择(0.8,1.0)。
P.S.值(0.2,0.4)是实际指示实际值在0.2到0.4之间变化的范围。我想现在我已经解释得更清楚了。谢谢你
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | def update(mylist, row, col, cmprow, cmpcol): lo, hi = mylist[row][col] low, high = mylist[cmprow][cmpcol] # always replace the current value if it's (-1, -1) if (lo, hi) == (-1, -1): mylist[row][col] = low, high print"replacing empty", row, col,"with", cmprow, cmpcol return # never replace the current value if the ranges don't overlap # or the other range is (-1, -1) if (low, high) == (-1, -1) or lo >= high or hi <= low: print row, col,"doesn't overlap", cmprow, cmpcol return # set the low to the highest low and the high to the lowest high print"updating", row, col,"with", cmprow, cmpcol mylist[row][col] = max((lo, low)), min((hi, high)) def update_ranges(oldlist): # make a copy of the list as we're going to modify it mylist = oldlist[:] # we don't need the row titles, they just complicate things rowtitles, mylist = zip(*mylist) rows = len(mylist) columns = range(len(mylist[0])) # for each row except the last for i in xrange(rows - 1): # update it by going down all the rows below it for k in xrange(i+1, rows): # for both columns for j in columns: update(mylist, i, j, k, j) # put the row titles back in mylist = zip(rowtitles, mylist) return mylist def test(): oldlist = [ ('a', [ (-1, -1), (0.2, 0.4) ] ), ('b', [ (0.3, 1.0), (-1, -1) ] ), ('c', [ (-1, -1), (-1, -1) ] ), ('d', [ (0.15, 0.35), (0.05, 0.15) ] ) ] print"Original List" print ' '.join(str(l) for l in oldlist) newlist = update_ranges(oldlist) print"New List" print ' '.join(str(l) for l in newlist) if __name__ == '__main__': test() |
编辑:更新