1

I am trying to make a dictionary using the output of a function I wrote (dct) that parses an income and spending .csv file. I designated "amount" as the total of the transaction. dct creates a dictionary that returns this:

spending = {
        'month': [],
        'payee': [],
        'amount': [],
        'category': [],
    }

The goal of this next function is to make a dictionary that sums all the "amount" outputs per "category" (only car, home, and food). This is my code so far, and it works. Still, I believe is not the most pythonic way to write it. Any ideas?

def summarize_by_category(dct):
    car, home, food = 0, 0, 0

    for (index,category) in enumerate( dct['category'] ):
        if "car" in category:
            car += dct['amount'][index]
        elif "food" in category:
            food += dct['amount'][index]
        elif "home" in category:
            home += dct['amount'][index]
    Totals = {
        'car': car,
        'food': food,
        'home': home,
    }
    return (Totals)
3
  • 3
    Could you give an example of what dct would contain? Commented Jun 10, 2020 at 1:13
  • 1
    Why are you using in category instead of == category? Can the category be cars, racecar, etc.? Commented Jun 10, 2020 at 1:21
  • 1
    Things would be easier if you didn't put categories and amounts in separate lists. Use a list of dictionaries: [{"category": "car", "amount": 10, "payee": "gas station", "month": "June"}, ...] Commented Jun 10, 2020 at 1:22

4 Answers 4

2

Not bad, I would say, but you can make this change:

def summarize_by_category(dct):
    Totals = {
        'car': 0,
        'food': 0,
        'home': 0
    }
    for category, amount in zip(dct['category'], dct['amount']):
        for key in Totals:
            if key in category:
                Total[key] += amount
    return (Totals)

So,

  • You don't reference the list directly. Instead, pair up the amount and cateogry on the fly
  • You can have more than three categories without much code change: just add the relevant key to the Totals dictionary

Here I assume your category is like "food for John" and "home utilities", if you can do exact match, you should use == instead of in for faster matching.

Sign up to request clarification or add additional context in comments.

1 Comment

Good idea using zip to pair up categories and amounts
1

I am not sure how your dct is structured - but this might be helpful:

def summarize_by_category(dct):
    Totals = {'car': 0, 'home': 0, 'food': 0}

    for index, category in enumerate( dct['category'] ):
        if "car" in category:
            Totals['car'] += dct['amount'][index]
        elif "food" in category:
            Totals['food'] += dct['amount'][index]
        elif "home" in category:
            Totals['home'] += dct['amount'][index]
    return (Totals)

Depending on how your dict is structured, this might work too:

def summarize_by_category(dct):
    return {k: sum(v) for k, v in dct.items()}

1 Comment

sums should be Totals
1

You can get rid of all the if/else if you just use the category as the key in the dictionary.

def summarize_by_category(dct):
    totals = {}
    for index, category in enumerate(dct['category']):
        if category in totals:
            totals[category] += dct['amount'][index]
        else:
            totals[category] = dct['amount'][index]
    return totals

If you're only interested in some categories, you can initialize the dictionary with those keys, and skip creating new keys.

def summarize_by_category(dct):
    totals = {'car': 0, 'home': 0, 'food': 0}
    for index, category in enumerate(dct['category']):
        if category in totals:
            totals[category] += dct['amount'][index]
    return totals

Comments

1

You could try something like this:

def summarize_by_category(dct):
    Totals = {'car': 0, 'home': 0, 'food': 0}

    for i in Totals.keys():
         Totals[i] = sum([dct['amount'][index] for (index,category) in enumerate( dct['category'] ) if i in category ])
    return Totals

Or, if you want a shorter way to do it, you could try something like this:

def summarize_by_category(dct):
    return {i:sum([dct['amount'][index] for (index,category) in enumerate( dct['category'] ) if i in category ]) for i in 'car,home,food'.split(',')}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.