Home > Back-end >  compare two attribute of objects from different list of object python
compare two attribute of objects from different list of object python

Time:10-12

I'm still pretty new to python and oop and I have some struggles resolving this problem without breaking the performance.

I want to compare the id of my user (that's what I have done with the eq function) and if the id is equal I want to know if their time attribute is greater than the other user who the id is the same

I retrieve my user from a different source, that's why I have to compare them.

class User:

    def __init__(self,id: str, time: int) -> None:
        self.id = id
        self.time = time

    def __eq__(self, __o: object) -> bool:
        return self.id == __o.id

list_user= [User(1, 20),User(2, 20),User(3, 45),...]
list_user2=[User(1, 5),User(4323, 20),User(3, 60),...]

for user in list_user:
        if user.id in list_user2 and user.time > list_user2:
            do_something()
        else:
            continue   

Can I retrieve the user that matches the user in user_list2 in the first condition to compare their times attribute?

How should I approach this problem?

CodePudding user response:

class User:

    def __init__(self,id: str, time: int) -> None:
        self.id = id
        self.time = time

    def __eq__(self, __o: object) -> bool:
        return self.id == __o.id


User(1, 20)
list_user = [User(1, 20), User(2, 20), User(3, 45)]
list_user2 = [User(1, 5), User(4323, 20), User(3, 60)]

for user in list_user:
    if user in list_user2:
        if user.time>list_user2[list_user2.index(user)].time:
            print(f"list1's user {user.id} time is bigger")
        else:
            print(f"list2's user {user.id} time is bigger")
    else:
        print("not found")

In line 17 I've just use the index of the first list's user to get the time value of the second lists user with the same id, then just compared it OUTPUT

list1's user 1 time is bigger
not found
list2's user 3 time is bigger

CodePudding user response:

class User:

    def __init__(self, _id: str, time: int) -> None:
        self.id = _id
        self.time = time


list_user = [User(1, 20), User(2, 20), User(3, 45), ...]
list_user2 = [User(1, 5), User(4323, 20), User(3, 60), ...]

list_user2_ids = [u.id for u in list_user2]

for user in list_user:
    try:
        identical_user = list_user2[list_user2_ids.index(user.id)]
        if user.time > identical_user.time:
            do_something()
    except:
        pass

CodePudding user response:

We could tweak User class a bit and make it hashable. This would allow us to convert the lists to sets and reduce the time required for looking up Users with matching ids:

class User:
   ...
   def __hash__(self) -> int:
        return hash(self.id)


list_user = [User(1, 20),User(2, 20),User(3, 45)]
list_user2 = [User(1, 5),User(4323, 20),User(3, 60)]

pairs = zip((set(list_user) & set(list_user2)), set(list_user2) & set(list_user))

for u1, u2 in pairs:
    if not u1.time > u2.time:  # negate the condition to avoid "else" statement
        continue
    do_something()

Because each list contains unique ids we can assume that a maximum of two matches will occur for each id, hence pairs. By making User hashable we're able to convert its lists to sets and find their intersection. The implementation with the set intersection should in theory reduce the time complexity from O(n2) to O(n) because we omit the second (nested) loop.

  • Related