Last week you formatted one campaign — one name, one spend, one CPL. Now imagine your CMO wants that for every campaign in the portfolio. All forty.
I'd duplicate the formula forty times in Excel. Which I've done. It's terrible.
In Python, you don't duplicate anything. A list holds all forty campaigns the way a column holds forty rows — except you can filter it, loop over every item, and stop the moment you find what you need. One variable, one collection, one loop. No copy-paste.
OK, I'll admit that sounds better than forty named cells. But how do you get from "here's a list" to "grouped by channel with CPL per group"?
That's the arc of the week. You start by filtering the list down to high-spend campaigns. Then you loop over it to compute CPL for each row. A while loop with a break finds the first campaign over target — no scanning the whole table by eye. A dict groups campaigns by channel the way a pivot does. And the final lesson nests those structures so each channel carries its own totals. By Friday, grouping forty campaigns by channel is a function call.
filter_high_spend: filter a list of campaign dicts by a spend thresholdcompute_cpl_per_campaign: for loop over the list, compute CPL for each rowfind_first_over_target: while loop + break — stop at the first over-target campaigngroup_by_channel: dict — accumulate campaigns into channel bucketschannel_summary: nested structures — totals and avg CPL per channelGoal: replace a manual pivot table with a function that groups forty campaigns by channel.
7 lessons this week
Last week you formatted one campaign — one name, one spend, one CPL. Now imagine your CMO wants that for every campaign in the portfolio. All forty.
I'd duplicate the formula forty times in Excel. Which I've done. It's terrible.
In Python, you don't duplicate anything. A list holds all forty campaigns the way a column holds forty rows — except you can filter it, loop over every item, and stop the moment you find what you need. One variable, one collection, one loop. No copy-paste.
OK, I'll admit that sounds better than forty named cells. But how do you get from "here's a list" to "grouped by channel with CPL per group"?
That's the arc of the week. You start by filtering the list down to high-spend campaigns. Then you loop over it to compute CPL for each row. A while loop with a break finds the first campaign over target — no scanning the whole table by eye. A dict groups campaigns by channel the way a pivot does. And the final lesson nests those structures so each channel carries its own totals. By Friday, grouping forty campaigns by channel is a function call.
filter_high_spend: filter a list of campaign dicts by a spend thresholdcompute_cpl_per_campaign: for loop over the list, compute CPL for each rowfind_first_over_target: while loop + break — stop at the first over-target campaigngroup_by_channel: dict — accumulate campaigns into channel bucketschannel_summary: nested structures — totals and avg CPL per channelGoal: replace a manual pivot table with a function that groups forty campaigns by channel.