关于python:比较和替换嵌套列表的元素

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

编辑:更新update_ranges以适用于任意数量的列。