简体   繁体   中英

Compare two elements in a Python list

I have a list of three complex numbers, two of them are conjugate of each other and I want to sort them out. Therefore I want to compare a pair of elements of the list and ask if their absolute values (or modulus) of the elements in the list are equal or not. If the comparison is true, sorting is done. See the code below. For testing, I did a single element comparison first (if the absolute value exceeds 4 or not). In the last comparison, I tried to use two variables x and y , but the syntax fails.

Can this be corrected or could there be some other tricks?

z = [complex(2.,-4.79583152), complex(2.,4.79583152), complex(0,1) ]
print('z=',z)

z = [x for x in z if abs(x) > 4]
print('z=',z)

z = [x for x in z and y for y in z if abs(x) == abs(y)] # This needs to modified
print('z=',z)

Output:

z= [(2-4.79583152j), (2+4.79583152j), 1j]
z= [(2-4.79583152j), (2+4.79583152j)]
Traceback (most recent call last):
  File "sort_complex.py", line 7, in <module>
    z = [x for x in z and y for y in z if abs(x) == abs(y)]
NameError: name 'y' is not defined

I want to get rid of this error and z= [(2-4.79583152j), (2+4.79583152j)] in the output as well in the last case.

As far as syntax is concerned, the line can be:

z = [(x, y) for x in z for y in z if abs(x) == abs(y)]

However, this will also match up each number with itself, and return both orderings for each pair. To avoid that, we can use enumerate , which gives us the index of each element, then pair them up with only the elements later in the list:

z = [
    (x, y)
    for (x_index, x) in enumerate(z)
    for y in z[x_index+1:]
    if abs(x) == abs(y)
]

Finally, using == on floating-point values is problematic, because of rounding; we will therefore need to allow a small difference:

z = [
    (x, y)
    for (x_index, x) in enumerate(z)
    for y in z[x_index+1:]
    if abs(abs(x) - abs(y)) < 0.01
]

Following @sabik's suggestion, I could think of a more compact one-liner:

z = [x for x in z for y in z if abs(x) == abs(y) and x != y]
print('z=',z)

And keeping a tolerance (say, 0.0001) for float comparison, this would be

z = [x for x in z for y in z if abs(abs(x) - abs(y) < 0.0001) and x != y]
print('z=',z)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM