Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic equivalent of this function?

Tags:

python

I have a function to port from another language, could you please help me make it "pythonic"?

Here the function ported in a "non-pythonic" way (this is a bit of an artificial example - every task is associated with a project or "None", we need a list of distinct projects, distinct meaning no duplication of the .identifier property, starting from a list of tasks):

@staticmethod
def get_projects_of_tasks(task_list):

    projects = []
    project_identifiers_seen = {}

    for task in task_list:

        project = task.project

        if project is None:
            continue

        project_identifier = project.identifier

        if project_identifiers_seen.has_key(project_identifier):
            continue

        project_identifiers_seen[project_identifier] = True
        projects.append(project)

    return projects

I have specifically not even started to make it "pythonic" not to start off on the wrong foot (e.g. list comprehension with "if project.identifier is not None, filter() based on predicate that looks up the dictionary-based registry of identifiers, using set() to strip duplicates, etc.)

EDIT:

Based on the feedback, I have this:

@staticmethod
def get_projects_of_tasks(task_list):

    projects = []
    project_identifiers_seen = set()

    for task in task_list:

        project = task.project

        if project is None:
            continue

        project_identifier = project.identifier

        if project_identifier in project_identifiers_seen:
            continue

        project_identifiers_seen.add(project_identifier)
        projects.append(project)

    return projects
like image 702
Robottinosino Avatar asked Dec 07 '22 14:12

Robottinosino


2 Answers

There's nothing massively unPythonic about this code. A couple of possible improvements:

  • project_identifiers_seen could be a set, rather than a dictionary.
  • foo.has_key(bar) is better spelled bar in foo
  • I'm suspicious that this is a staticmethod of a class. Usually there's no need for a class in Python unless you're actually doing data encapsulation. If this is just a normal function, make it a module-level one.
like image 190
Daniel Roseman Avatar answered Dec 25 '22 22:12

Daniel Roseman


What about:

project_list = {task.project.identifier:task.project for task in task_list if task.project is not None}
return project_list.values()

For 2.6- use dict constructor instead:

return dict((x.project.id, x.project) for x in task_list if x.project).values()
like image 45
Charles Brunet Avatar answered Dec 25 '22 21:12

Charles Brunet