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 User
s 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.