1

I have a problem in the code for my function isSymmetric, which tests if a relation is symmetric. In the following, I am going to describe my problem further. It is important to mention that I am only allowed to use list comprehension and the any-or all-functions. At first here is my code:

def isSymmetric(base_amount, relation):
    return all([(a,b) in relation and (b,a) in relation for a in base_amount and b in base_amount])


print(isSymmetric([1,2,3], [(1,2),(2,1),(2,2),(1,3),(3,1)]))   #needs to be true
print(isSymmetric([1,2,3], [(1,2),(2,1),(2,2),(1,3)]))         #needs to be false

The problem is that my first output is declared False, even though all the relations are symmetric.

I guess the problem is, that there aren't all possible symmetric relations in the tuples, for example (2,3) and (3,2) aren't included. It has to be true, but I can't come to the conclusion on how to still get True in the first one. I am a beginner and I can't find any helpful material anywhere, on how to really code relations in list comprehension. I would really appreciate a tip or any approach.

tzaman
  • 46,925
  • 11
  • 90
  • 115
  • 1
    Did you mean `for a in base_amount for b in base_amount`? An `and` in that position is incorrect syntax. – tzaman Nov 11 '22 at 20:12
  • Assuming that's the case, your current code is checking if _all possible relations_ from the candidate set exist, but for example `(2, 3)` is not present in the list which is why you're getting a `False` result. – tzaman Nov 11 '22 at 20:13
  • Like you say, you are now evaluating that all combinations exist, while you should check for every combination whether either both relations or none of the relations exist. You are very close to that :). An alternative approach could be to check for every relation whether its counterpart exists. You don't need the base_amount variable for that. – QuadU Nov 11 '22 at 20:18

1 Answers1

0

If you just need to check whether a symmetric relation exists in for every tuple in the list, you don't need the base_amount at all:

def isSymmetric(relation):
    return all((b, a) in relation for (a, b) in relation)

isSymmetric([(1,2),(2,1),(2,2),(1,3),(3,1)])  # True
isSymmetric([(1,2),(2,1),(2,2),(1,3)])        # False

If for some reason you need to construct your pairs from the individual elements, you can do that too by putting a condition in the list-comp, so it only checks the mirror if the forward pair exists:

def isSymmetric(base_amount, relation):
    return all((b, a) in relation for a in base_amount for b in base_amount if (a, b) in relation)

isSymmetric([1,2,3], [(1,2),(2,1),(2,2),(1,3),(3,1)])  # True
isSymmetric([1,2,3], [(1,2),(2,1),(2,2),(1,3)])        # False
tzaman
  • 46,925
  • 11
  • 90
  • 115
  • Thank you for your answer. According to the task, It has to be a relation over the base values 1,2,3 and It has to be printed like in my post:) –  Nov 11 '22 at 20:26
  • @AleksandarBakovic see my update for how to do it using the base values. :) – tzaman Nov 11 '22 at 20:27
  • Thank you, you really helped me. I still need to wrap my head arround it, in order to understand it. Much love –  Nov 11 '22 at 20:30