Python Forum
Compare each n-th element of a nested list
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Compare each n-th element of a nested list
#1

Hey mates! I've been pounding my head against this problem for the last 2 weeks so I think it's time to get some help! Wall
I have a nested list like
oldljp = [[['0:0:0'], 1, 2, 3, 4], [['0:0:1'], 1, 2, 5, 4], [['0:0:3'], 1, 2, 9, 3], [['0:0:4'], 1, 2, 8, 1], [['1:0:0'], 1, 4, 3, 6], [['1:0:1'], 1, 5, 7, 8], [['2:1:1'], 1, 4, 3, 4], [['2:3:8'], 1, 1, 1, 1]]
(The real-life list is several hundred sublists long). :)

Here's what I have to do...
1. Only compare nested lists that begin with the same first number (this first number defines the radiation treatment field that the sublists are within). For instance, the first four all begin with 0, so I will be comparing only over those four, then comparing only the two that begin with 1, then only the two that begin with 2. It's safe to assume that this is always increasing numerically.
2. Okay, now for each sublist that meets the criteria above:
   (a). Compare each element. Is oldljp[0][1] == oldljp[1][1] == oldljp[2][1] and so on.
    (b). If so, I want to string the element.
After this runs, I would hopefully have something like
oldljp = [[['0:0:0'], '1', '2', 3, 4], [['0:0:1'], '1', '2', 5, 4], [['0:0:3'], '1', '2', 9, 3], [['0:0:4'], '1', '2', 8, 1], [['1:0:0'], '1', 4, 3, 6], [['1:0:1'], '1', 5, 7, 8], [['2:1:1'], '1', 4, 3, 4], [['2:3:8'], '1', 1, 1, 1]]
So far I've tried a combination of for loops 4 levels deep, zipping, setting up a Pandas dataframe, and using Numpy. I've never gotten any of these to work. My most recent attempt is below:
def randMlcVmat(self, oldljp):
    '''
    Add random motion to the provided sequence of Leaf Jaw Positions and
    return the new values for later use.
    '''


    # Get a list of beam sequences. Note that this depends on the oldljp
    # list passed to the function - since the conebeam sequence is always
    # removed and other sequences may also be removed, the number of beam
    # sequences found here may not be the same as in the original RP*.dcm.
    beamSeq =
    if self.ui.checkBox_staticLeaves.isChecked():
        for index, seq in enumerate(oldljp):
            if seq[0][0].split(':')[0] not in beamSeq:
                beamSeq.append(seq[0][0].split(':')[0])

    beamRange =
    for beam in beamSeq:
        beamHold =
        for cpIndex, cp in enumerate(oldljp):
            # print('cp: %r beam: %r' % (cp[0][0].split(':')[0], beam))
            # print(cp[0][0].split(':')[0] == beam)
            if cp[0][0].split(':')[0] == beam:
                beamHold.append(cpIndex)
        beamRange.append(beamHold)

    # print(beamRange)

    for bRange in beamRange:
        flip90 = list(zip(*oldljp[bRange[0]:bRange[-1] + 1]))
        # print(flip90)
        for lIndex, leafSeq in enumerate(flip90):
            if leafSeq.count(leafSeq[0]) == len(leafSeq):
                print(flip90[lIndex])
               
# From here I always lose my way.
...and then other unrelated code
I'd be grateful for any help!
Thanks!
Fred
OS: Arch
Editor: Atom with Material Syntax UI and the Termination terminal plugin

Micah 6:8
Reply
#2
Maybe this helps (C-like, not very pythonish):

#!/usr/bin/python3
OLDLJP = [[['0:0:0'], 1, 2, 3, 4],
          [['0:0:1'], 1, 2, 5, 4],
          [['0:0:3'], 1, 2, 9, 3],
          [['0:0:4'], 1, 2, 8, 1],
          [['1:0:0'], 1, 4, 3, 6],
          [['1:0:1'], 1, 5, 7, 8],
          [['2:1:1'], 1, 4, 3, 4],
          [['2:3:8'], 1, 1, 1, 1]]

NEWLJP = [[['0:0:0'], '1', '2', 3, 4],
          [['0:0:1'], '1', '2', 5, 4],
          [['0:0:3'], '1', '2', 9, 3],
          [['0:0:4'], '1', '2', 8, 1],
          [['1:0:0'], '1',  4,  3, 6],
          [['1:0:1'], '1',  5,  7, 8],
          [['2:1:1'], '1',  4,  3, 4],
          [['2:3:8'], '1',  1,  1, 1]]

def calculategroup(list, start, end):
   #print(start, end)
    for x in range(1, 5):
        equal = True
        for y in range(start+1, end):
            if list[y-1][x] != list[y][x]:
                equal = False
                break
        if equal:
            for y in range(start, end):
               list[y][x] = str(list[y][x])

def calculate(list):
    start = 0
    for i in range(1, len(list)):
        if list[i-1][0][0][0] != list[i][0][0][0]:
            calculategroup(list, start, i)
            start = i
    calculategroup(list, start, len(list))


calculate(OLDLJP)
print(OLDLJP)
if OLDLJP == NEWLJP:
   print("ok")
else:
   print("wrong")
#done
Reply
#3
Thank you very much heiner55! I don't think that would quite have done what I was looking for (it looks like it expects NEWLJP to already exist and contain strings?) but I did learn a way by using numpy:
       
beamSeq =
for index, seq in enumerate(oldljp):
    if seq[0][0].split(':')[0] not in beamSeq:
        beamSeq.append(seq[0][0].split(':')[0])

# Get the range of sequences in the plan that lie within each beam.
beamRange =
for beam in beamSeq:
    beamHold =
    for cpIndex, cp in enumerate(oldljp):
        if cp[0][0].split(':')[0] == beam:
            beamHold.append(cpIndex)
    beamRange.append(beamHold)

# Temporarily transition to numpy for easier analysis.
numpyset = np.asarray(oldljp)

# For each beam, if a leaf does not move throughout the entire beam,
# string it so it won't be moved later in the code.
for bRange in beamRange:
    subset = numpyset[bRange[0]:bRange[-1] + 1]
    flip = subset.T
    for row in range(len(flip)):
        if len(np.unique(flip[row])) == 1:
            flip[row] = np.asarray(flip[row], dtype=str)
    numpyset[bRange[0]:bRange[-1] + 1] = flip.T

# Convert back to Python lists
newljp = numpyset.tolist()
Quite possibly there are better, more pythonic ways to do this (or I could probably have used numpy's properties more effectively and not needed to transpose the array) but this seems to work quite well.
Thanks again!
Fred
OS: Arch
Editor: Atom with Material Syntax UI and the Termination terminal plugin

Micah 6:8
Reply
#4
My program and your program yields the same result.
So we have done it both in the right way.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Convert element of list to integer(Two dimentional array) zorro_phu 3 4,632 Jun-12-2018, 04:49 AM
Last Post: zorro_phu

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020