This notebook is inspired from one of the projects I was pursuing during the final year of my PhD. I was dealing with several (of the order of hundred thousands) pair of numbers. My main goal was to identify swapped pairs and assign the swapped pair, the value of J corresponding to the original pair. For example, in the table below, (1,9) after swapping is (9,1) and therefore, (9,1) is the swapped pair. Then this swapped pair is assigned the value of J corresponding to the original pair (1,9) which is 3.45.

\begin{array}{|c|c|c|}\hline Atom_1&Atom_2&J\\\hline 1&9&3.45\\\hline 2&8&1.67\\\hline 3&7&8.97\\\hline 4&6&2.12\\\hline 5&5&9.12\\\hline 6&4&-\\\hline 7&3&-\\\hline 8&2&-\\\hline 9&1&-\\\hline \end{array}

Here's how I accomplished this:

  1. Create a separate list for original and swapped numbers
  2. Create an empty list to store repeated J values
  3. Then loop over the swapped pair list
    • For each pair, reverse it and check if it is present in the original pair list
    • Get the corresponding index and use that index to locate value of J
    • Append the value of J to the empty list created earlier
  4. Add both lists containing unique J values and repeated J values
  5. All done!
# Load some useful libraries

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

Let's first generate some pairs similar to the table above

# Note that we use list comprehension here as it is more efficient than using a for loop!
pairs = [(i,j) for i,j in zip(range(1,10,1), range(9,0,-1))]
print("Generated pairs are = ", pairs)
Generated pairs are =  [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4), (7, 3), (8, 2), (9, 1)]

Let's now separate orignal and swapped pairs

original_pairs = []  # Create an empty list for original pairs
swapped_pairs = []   # Create an empty list for swapped pairs

for pair in pairs:
  if pair[::-1] not in original_pairs:
    original_pairs.append(pair)
  else:
    swapped_pairs.append(pair)
  
print("Original pairs are = ", original_pairs)

print("Swapped pairs are = ", swapped_pairs)
Original pairs are =  [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)]
Swapped pairs are =  [(6, 4), (7, 3), (8, 2), (9, 1)]

Numbers for column J corresponding to original pair

unique_J= [3.45, 1.67, 8.97, 2.12, 9.12]
repeated_J = []
for swapped_pair in swapped_pairs:
  if swapped_pair[::-1] in original_pairs:
    # get corresponding coupling index and append to repeated_J list
    coupling_index = original_pairs.index(swapped_pair[::-1])
    repeated_J.append(unique_J[coupling_index])
print("Repeated J's are: ", repeated_J)
Repeated J's are:  [2.12, 8.97, 1.67, 3.45]

Let's now combine repeated J's with unique J's

J = unique_J + repeated_J 
print("Pair", "\t", "J")
for i, j in zip(pairs, J):
  print(i,"\t", j)
Pair 	 J
(1, 9) 	 3.45
(2, 8) 	 1.67
(3, 7) 	 8.97
(4, 6) 	 2.12
(5, 5) 	 9.12
(6, 4) 	 2.12
(7, 3) 	 8.97
(8, 2) 	 1.67
(9, 1) 	 3.45

One can see now that the value of J for the original and the swapped pair is identical.

Please note that the number of pairs I had in my original task was around 100,000 which lead to a slower performance of the code above. Please let me know if you know a more efficient way to do this.

Thanks for reading!