Reputation: 811
I have got a list which is:
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)]
}
I have to get an output which will be like the following:
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)]
}
The list above looks like this when I print it,
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) ] ) ]
Now the algorithm is like the following:
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).
This process carries till 'a' is compared to the last element in the list here its upto 'd'. Then comes the turn of 'b' and same thing will continue between 'b' and 'c' then 'b and 'd' and so on.
The other rules when comparison between two actual ranges (0.1,0.3) and (0.5,1.0).
Say if two ranges totally overlap like (0.1, 0.8) and (0.3, 0.9) then, it should take the common between them which is (0.3, 0.8).
If they don't overlap like (0.1, 0.4) and (0.5, 0.9) then, it should choose its own which is (0.1, 0.4).
And if they partially overlap then also take the common between them. Like (0.4, 1.0) and (0.8, 1.5) then it should choose (0.8, 1.0).
P.S. The values (0.2, 0.4) are the ranges actually indicating the actual value will vary between 0.2 to 0.4. I think now I have explained a bit more clearly. Thank you
Upvotes: 0
Views: 794
Reputation: 176750
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 '\n'.join(str(l) for l in oldlist)
newlist = update_ranges(oldlist)
print "New List"
print '\n'.join(str(l) for l in newlist)
if __name__ == '__main__':
test()
Edit: Updated update_ranges
to work for any number of columns.
Upvotes: 1