0
\$\begingroup\$

I have a list that can have up to three elements, and I want to append them to three list, because I get this list from another element within a loop. My final goal is to have a dataframe with the data of all elements. I have coded this:

affected_projects_1 = []
affected_projects_2 = []
affected_projects_3 = []

for issue in project:
    affected_projects = issue.affected_projects
    try:
        affected_projects_1.append(affected_projects[0])
    except IndexError:
        affected_projects_1.append('')
    except:
        raise Exception
    try:
        affected_projects_2.append(affected_projects[1])
    except IndexError:
        affected_projects_2.append('')
    except:
        raise Exception
    try:
         affected_projects_3.append(affected_projects[2])
    except IndexError:
        affected_projects_3.append('')
    except:
        raise Exception

 df = pd.DataFrame(zip(affected_projects_1, affected_projects_2, affected_projects_3))

This piece of code seems pretty verbose and almost repetitive (the only thing that changes is the number). How could I make it more compact? Is that even possible without losing readability or using antipatterns (i.e using globals variables). Thanks

\$\endgroup\$
  • \$\begingroup\$ What do you mean by I want to append them to three list, because I get this list from another element within a loop? \$\endgroup\$ – AMC Dec 23 '19 at 1:50
  • \$\begingroup\$ Sorry for not being clear enough. I am getting info from Redmine (project management tool), which consist in a series of issues (tickets, tasks, whatever you want to call them) that contains info like name, author(s), hours spent etc. I am doing a loop for all the issues, and for each info field, I create before the loop an empty list, and in each iteration I append the value of the field to the list, so that at the end I can create a dataframe zipping the lists. So for instance: authors_list = []; for issue in issues: authors_list.append(issue.author). \$\endgroup\$ – Javier López Tomás Dec 23 '19 at 16:53
2
\$\begingroup\$

except: raise Exception is awful.

  1. It converts all errors to Exception.

    • This means errors that have nothing to do with Exception like BaseException and KeyboardInterupt are now something they semantically are not.
    • This also means if you have a KeyError then it's magically the same as any other error.
  2. It doesn't even raise an exception instance, Exception().

  3. There's no need for it, just remove it from your code.

If you weren't appending to different lists then we could see that all we need is a basic for loop.

for proj in issue.affected_projects[:3]:
    affected.append(proj)

Since you have to append to other lists you can zip over them.

for affected, proj in zip(affected_projects, issue.affected_projects):
    affected.append(proj)

Since you need to default to '' you can just extend issue.affected_projects to these values.

affected_projects = [[], [], []]
for issue in project:
    for affected, proj in zip(
        affected_projects,
        issue.affected_projects + 3*['']
    ):
        affected.append(proj)

We can remove the need for affected.append by moving the zip up one loop.

affected_projects = zip(*(
    (issue.affected_projects + 3*[''])[:3]
    for issue in project
))
pd.DataFrame(zip(*affected_projects))

Since you are ziping affected_projects and you're zipping issue.affected_projects you don't really need to zip at all.

df = pd.DataFrame(
    (issue.affected_projects + 3*[''])[:3]
    for issue in project
)
\$\endgroup\$
  • \$\begingroup\$ Thanks for your answer. If I remove except Exception, what happens when there is an error but it is not IndexError? \$\endgroup\$ – Javier López Tomás Dec 20 '19 at 14:03
  • 2
    \$\begingroup\$ @JavierLópezTomás It propagates up as if there were no try. \$\endgroup\$ – Peilonrayz Dec 21 '19 at 11:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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