title: Map and work with (X, Y), (X,Z) and (Y,Z) pairs and associated X, Y or Z coordinates
body: <p>I have a list of lists <code>nLedgers</code> - a 3D cloud of points:</p>
  
  <pre><code>[nodeID, X, Y, Z]
  </code></pre>
  
  <p>with multiple rows. Some nodes will have the same <code>X</code> and <code>Y</code> coordinates and different <code>Z</code> coordinate.</p>
  
  <p>I'd like to, first identify the different <code>Z</code> coordinates which have the same <code>X</code> and <code>Y</code> coordinates.
  Then the same for <code>X</code>, and finally for <code>Y</code>.</p>
  
  <p>Then, using those <code>(X,Y)</code>, <code>(X,Z)</code> or <code>(Y,Z)</code> pairs and different <code>Z</code>, <code>Y</code>or <code>X</code> levels I'd like to change the <code>x</code> and <code>y</code> coordinates of a second list (<code>nodes</code>).</p>
  
  <p>The changes should respect the following:</p>
  
  <pre><code>1) For x,y,z in `nodes`, if x=X and y=Y and Z level 1 &lt;=z&lt; Z level 2:
     change x and y coordinates between consecutive `Z` levels, for each pair of `(X,Y)` coordinates.
  
  2) For x,y,z in `nodes`, if x=X and Y level 1 &lt;=y&lt; Y level 2:
     change x coordinates between consecutive `Y` levels, for each pair of `(Y,Z)` coordinates.
  
  3) For x,y,z in `nodes`, if y=Y and X level 1 &lt;=x&lt; X level 2:
     change y coordinates between consecutive `X` levels, for each pair of `(X,Z)` coordinates.
  </code></pre>
  
  <p>Any help is appreciated.</p>
  
  <p>Based on previous posts I have the following code:</p>
  
  <pre><code>from ast import literal_eval
  nLedgers=[[literal_eval(x) for x in item] for item in nLedgers] #transform list of strings to list of floats
  nodes=[[literal_eval(x) for x in item] for item in nodes]
  
  NewNodesCoord = []
  dirX=1 #integer that changes the direction (X,Y) of the vector to change the x and y coordinates
  dirY=1-dirX
  newy1=0 #float that stores the new y coordinate at x=X1 and z=Z 
  newy2=0 #float that stores the new y coordinate at x=X2 (X2&gt;X1) and z=Z 
  newx1=0 #float that stores the new x coordinate at y=Y1 and z=Z 
  newx2=0 #float that stores the new x coordinate at y=Y2 (Y2&gt;Y1) and z=Z 
  
  from collections import defaultdict
  dic1=defaultdict(list) #dictionary of X and Y pairs
  dic2=defaultdict(list) #dictionary of X and Z pairs
  dic3=defaultdict(list) #dictionary of Y and Z pairs
  
  for id,x,y,z in nLedgers:
      dic1[(x,y)].append((id,z))
  for key in dic1:
      dic1[key].sort( key=lambda x:float(x[1]) )
  
  for id,x,y,z in nLedgers:
      dic2[(x,z)].append((id,y))
  for key in dic2:
      dic2[key].sort( key=lambda x:float(x[1]) )
  #print dic2
  
  for id,x,y,z in nLedgers:
      dic3[(y,z)].append((id,x))
  for key in dic2:
      dic3[key].sort( key=lambda x:float(x[1]) )
  #print dic3
  
  newNodes=[] #list with changed coordinates
  for i,row in enumerate(nodes): #same X,Y, different Z
      id,x,y,z=row
      z_levels=[item[1] for item in dic1[(x,y)]]
      for k,l in zip(z_levels,z_levels[1:]):
          if k&lt;=z&lt;l:
              nodes[i][1]=x+((l-k)/400*sin(pi*(z-k)/l)+max(z_levels)/800*(z/max(z_levels)))*dirX
              nodes[i][2]=y+((l-k)/400*sin(pi*(z-k)/l)+max(z_levels)/800*(z/max(z_levels)))*dirY
              nodes[i][3]=z
              newNodes.append([nodes[i][0], nodes[i][1], nodes[i][2], nodes[i][3]])
  #           break 
  
  for i,row in enumerate(nodes):  #same X, different Y
      id,x,y,z=row
      y_levels=[item[1] for item in dic2[(x,z)]]
      z_levels=[item[1] for item in dic1[(x,y)]]
      for k,l in zip(y_levels,y_levels[1:]):
          if x==dic2.keys()[0][0] and k&lt;y&lt;l:
              for m,n in zip(z_levels,z_levels[1:]):
                  if m==z and y==k:
                      newx1=x+((n-m)/400*sin(pi*(z-m)/n)+max(z_levels)/800*(z/max(z_levels)))*dirX
                  if m==z and y==l:
                      newx2=x+(n-m)/400*sin(pi*(z-m)/n)+max(z_levels)/800*(z/max(z_levels))   
              nodes[i][1]=x+(y-k)*(newx2-newx1)/(l-k)+newx1
              nodes[i][2]=y
              nodes[i][3]=z
              newNodes.append([nodes[i][0], nodes[i][1], nodes[i][2], nodes[i][3]])
  
  for i,row in enumerate(nodes):#same Y, different X
      id,x,y,z=row
      x_levels=[item[1] for item in dic3[(y,z)]]
      z_levels=[item[1] for item in dic1[(x,y)]]
      for k,l in zip(x_levels,x_levels[1:]):
  #        print dic3.keys()[0][0]
          if y==dic3.keys()[0][0] and k&lt;x&lt;l: #same X, different Y
              for m,n in zip(z_levels,z_levels[1:]):
                  if m==z and y==k:
                      newy1=y+((n-m)/400*sin(pi*(z-m)/n)+max(z_levels)/800*(z/max(z_levels)))*dirY
                  if m==z and y==l:
                      newy2=y+((n-m)/400*sin(pi*(z-m)/n)+max(z_levels)/800*(z/max(z_levels)))*dirY  
              nodes[i][1]=x
              nodes[i][2]=y+(y-k)*(newy2-newy1)/(l-k)+newy1
              nodes[i][3]=z
              newNodes.append([nodes[i][0], nodes[i][1], nodes[i][2], nodes[i][3]])
  </code></pre>
  
  <p>The first change is working (the X,Y pair), the other two aren't working. I've got a problem in <code>dic2.keys()[0][0]</code>. I'd like to loop over the keys of dic2 and compare the value of the first key with x.</p>