比较和替换嵌套列表的元素

时间:2011-08-04 22:11:19

标签: python

我有一个列表:

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)]
          }

我必须得到一个如下所示的输出:

 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)]
          }

当我打印时,上面的列表看起来像这样,

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) ] ) ]

现在算法如下:

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 个答案:

答案 0 :(得分:1)

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()

修改:更新update_ranges以适用于任意数量的列。