bdoubleu
bdoubleu

Reputation: 6107

List comprehension, value if not in second list

Is it possible to use list comprehension to get the sales for each week if the week exists in sales else 0?

weeks = [{'week': 31}, {'week': 32}, {'week': 33}, 
         {'week': 34}, {'week': 35}, {'week': 36}]
weeks = [x['week'] for x in weeks]

sales = [
    {'week': 32, 'sales': 1167.26}, 
    {'week': 33, 'sales': 1373.61}, 
    {'week': 36, 'sales': 1491.43}, 
]

expected = [0, 1167.26, 1373.61, 0, 0, 1491.43]

Upvotes: 2

Views: 70

Answers (4)

mad_
mad_

Reputation: 8273

If you are okay to use third party libraries like pandas

import pandas as pd
weeks = [{'week': 31}, {'week': 32}, {'week': 33}, 
         {'week': 34}, {'week': 35}, {'week': 36}]
df1=pd.DataFrame(weeks)    

sales = [
    {'week': 32, 'sales': 1167.26}, 
    {'week': 33, 'sales': 1373.61}, 
    {'week': 36, 'sales': 1491.43}, 
]
df2=pd.DataFrame(sales)

df1.merge(df2,how='left').fillna(0)

Output

week    sales
31      0.00
32      1167.26
33      1373.61
34      0.00
35      0.00
36      1491.43

In case you have multiple entries in the sales list for same week

import pandas as pd
weeks = [{'week': 31}, {'week': 32}, {'week': 33}, 
         {'week': 34}, {'week': 35}, {'week': 36}]
df1=pd.DataFrame(weeks) 

sales = [
    {'week': 32, 'sales': 1167.26}, 
    {'week': 33, 'sales': 1373.61}, 
    {'week': 36, 'sales': 1491.43}, 
    {'week': 36, 'sales': 5}, 
]
df2=pd.DataFrame(sales)

pd.DataFrame(df1.merge(df2,how='left').fillna(0).groupby('week')['sales'].sum(name='sales'))

week    sales
31      0.00
32      1167.26
33      1373.61
34      0.00
35      0.00
36      1496.43

Inspired by @Ajax1234's solution, in case you have multiple values in sales for one week you can create a dict with grouped values

weeks = [{'week': 31}, {'week': 32}, {'week': 33}, 
         {'week': 34}, {'week': 35}, {'week': 36}]
sales = [
    {'week': 32, 'sales': 1167.26}, 
    {'week': 33, 'sales': 1373.61}, 
    {'week': 36, 'sales': 1491.43}, 
    {'week': 36, 'sales': 5}, 
]

sales_dict={}
for i in sales:
    if i['week'] in sales_dict:
        sales_dict[i['week']]=sales_dict[i['week']]+i['sales']
    else:
        sales_dict[i['week']]=i['sales']
[sales_dict.get(i['week'],0) for i in weeks] # sales_dict= {32: 1167.26, 33: 1373.61, 36: 1496.43}

Output

[0, 1167.26, 1373.61, 0, 0, 1496.43]

Upvotes: 0

Cosmic Ossifrage
Cosmic Ossifrage

Reputation: 5379

If you guarantee there is only one element of sales for any given week value, you can obtain a sequence of sales values which you sum over to obtain the values for any given week:

out = [
    sum(sale['sales'] for sale in sales if sale['week'] == week)
    for week in weeks
]

If there are multiple entries in sales for any given week number, their results will be summed to produce an aggregate value of the sales output.

This gives you a single list comprehension with the desired output:

Output:

[0, 1167.26, 1373.61, 0, 0, 1491.43]

Upvotes: 0

bipll
bipll

Reputation: 11940

Say, create an intermediate mapping of week number to sales, something like

week_sales = {s['week']: s['sales'] for s in sales}

expected = [week_sales.get(w['week'], 0) for w in weeks]

Upvotes: 0

Ajax1234
Ajax1234

Reputation: 71461

You can create a dictionary from sales to use as a lookup for each week in weeks:

weeks = [{'week': 31}, {'week': 32}, {'week': 33}, 
     {'week': 34}, {'week': 35}, {'week': 36}]

sales = [
{'week': 32, 'sales': 1167.26}, 
{'week': 33, 'sales': 1373.61}, 
{'week': 36, 'sales': 1491.43}, 
]
_sales = {i['week']:i['sales'] for i in sales}
results = [_sales.get(i['week'], 0) for i in weeks]

Output:

[0, 1167.26, 1373.61, 0, 0, 1491.43]

Upvotes: 3

Related Questions