1
\$\begingroup\$

I have two lists:

  1. Users - [<UserObject1>, <UserObject2>, ...]
  2. Contributions - [<ContributionObject1>, <ContributionObject2>, ...]

Every ContributionObject further can have single or multiple UserObject in it which are mentioned as person_links here and both the objects that are ContributionObject and UserObject has certain methods and attributes.

UserObject has an attribute affiliation.

I have to check whether UserObject from Users and have the same affiliation to one of the UserObject from ContributionObject from Contributions.

If yes, I have to make a dictionary where key will be the user from Users and value will be an array of ceratin ContributionObject attributes that is title and url.

I am able to do it with the following logic.

I wanted to ask if this logic can be improved further?

If there is another efficient way to do this task, do mention that. Thanks for all the help. :)

conflicts = dict()
for user in users:
    if user.affiliation:
        for contribution in contributions:
            if not conflicts.get(user):
                conflicts[user] = [
                    (
                        contribution.title,
                        contribution.url,
                    )
                    for person in contribution.person_links
                    if user.affiliation in person.affiliation
                ]
            else:
                conflicts[user] += [
                    (
                        contribution.title,
                        contribution.url,
                    )
                    for person in contribution.person_links
                    if user.affiliation in person.affiliation
                ]

I tried to find out better ways to update dict values on SO but they were mostly about updating the existing values(overriding) not about adding(appending) to an existing value.

\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Considering DRY principal, this

if not conflicts.get(user):
    conflicts[user] = [
                (
                    contribution.title,
                    contribution.url,
                )
                for person in contribution.person_links
                if user.affiliation in person.affiliation
            ]
else:
    conflicts[user] += [
                (
                    contribution.title,
                    contribution.url,
                )
                for person in contribution.person_links
                if user.affiliation in person.affiliation
            ]

can and should be replaced with a defaultdict:

from collections import defaultdict

conflicts = defaultdict(list)
...
for contribution in contributions:
    conflicts[user].extend((contribution.title, contribution.url)
                           for person in contribution.person_links
                           if user.affiliation in person.affiliation)

Or at least take advantage of dict.setdefault (while preferring a dict literal over a call to dict to save method look-up time):

conflicts = {}
...
for contribution in contributions:
    conflicts.setdefault(user, []).extend((contribution.title, contribution.url)
                                          for person in contribution.person_links
                                          if user.affiliation in person.affiliation)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.