Compare list elements with a catch: reciprocal comparisons must occur FIRST…also element order matters

jython
imagej
python

#1

I am writing a script in Jython/Python for image analysis (using ImageJ). My goal is to compare the images to eachother…

(edit for clarity: Each element in the list must be compared to every other element, but self-comparisons are not allowed.)

…but I have some specific requirements. These requirements are based on the fact that I’m using a predefined plugin.

For example:

i magefiles = ["A", "B", "C"]

First: order matters. "A" vs "B" is different than"B" vs. “A”.

Second: the list is of variable size, based on user input. In this example, the user has input 3 files: A,B,C, but the code needs to accomodate instances where the number of elements does not equal three.

Third: self-comparison is not allowed. Ie: "A" vs. "A" cannot occur.

Fourth: I would like the comparisons be reciprocated before moving onto the next element. For example:

"A" vs "B" then "B" vs "A" rather than "A" vs "B" then "A" vs "C"

Fifth: I ultimately need to access the elements in the form of a string (requirement due to calling user-defined variables into a preexisting plugin).

For clarity, the comparisons that must be made are:

"A" vs "B"
"B" vs "A"
"A" vs "C"
"C" vs "A"
"B" vs "C"
"C" vs "B"

I’m able to produce a code that does everything except the FOURTH requirement…that is reciprocal comparisons first. But I’m really stuck on how to make the the order of comparisons what I want. Here’s the current working snipped, that does not meet my 4th requirement.

from ij import IJ  #using Jython scripting in the ImageJ program

`imagefiles = ["A", "B", "C"]`

for index, imgs in enumerate(imagefiles):

    for s, secondimage in enumerate(imagefiles):
        if s != index:
            IJ.run("PluginFE", "element1="+imgs+" element2="+secondimage) #this calls the plugin (PluginFE) within the ImageJ program)

I’m trying to think about how to accomplish the comparison order requirement…and coming up with something like this:

for imgs in imagefiles:

for index in range(len(imagefiles)):
  if index < len(imagefiles):
    IJ.run("PluginFE", "element1="+imgs+"element2="+imagefiles[index+1])

but this fails with the error

IndexError: index out of range: 3

I understand the error,and the problem…I just can’t figure out how to work around. I’m still pretty new to coding, so I may be missing an obvious python function!

Thanks for any input


#2

It looks to me like your first bit of Python has the right idea. I am not clear on what the point of posting the second bit is. I think you should be able to get what you want this way.

from ij import IJ
imagefiles = ["A", "B", "C"]
for index1, img1 in enumerate(imagefiles):
    for index2, img2 in enumerate(imagefiles):
        if index2 > index1:
            IJ.run("PluginFE", "element1="+img1+" element2="+img2)
            IJ.run("PluginFE", "element1="+img2+" element2="+img1)

#4

If you want it to be a little cleaner, slice the lists to avoid the if statement.

from ij import IJ
for index1, img1 in enumerate(imagefiles[:-1]):
    for img2 in imagefiles[index1 + 1:]:
            IJ.run("PluginFE", "element1=" + img1 + " element2=" + img2) 
            IJ.run("PluginFE", "element1=" + img2 + " element2=" + img1) 

Or, if you know a given image will only show up once in your imagefiles list, you can swap the enumerate for an index function, and get this

from ij import IJ
for img1 in imagefiles[:-1]:
    for img2 in imagefiles[imagefiles.index(img1) + 1:]:
            IJ.run("PluginFE", "element1=" + img1 + " element2=" + img2) 
            IJ.run("PluginFE", "element1=" + img2 + " element2=" + img1) 

(This fails for a situation of imagefiles = ["A", "A", "C"])