0

i am now learning list comprehensions, and want to replace a lengthy if statement with an elegant list comprehension. The following if statement is what I want to convert to comprehension list below it. The comprehension list doesn't do what I want to do yet, but atleast you can see where I am trying to go with it.

would like the list comprehension to only give back one value as how the if statement will.

Thank you in advance

weight_kg = 8

if weight_kg <= 0.25:
    price_weight = 2.18
elif weight_kg <= 0.5:
    price_weight = 2.32
elif weight_kg <= 1:
    price_weight = 2.49
elif weight_kg <= 1.5:
    price_weight = 2.65
elif weight_kg <= 2:
    price_weight = 2.90
elif weight_kg <= 3:
    price_weight = 4.14
elif weight_kg <= 4:
    price_weight = 4.53
elif weight_kg <= 5:
    price_weight = 4.62
elif weight_kg <= 6:
    price_weight = 5.28
elif weight_kg <= 7:
    price_weight = 5.28
elif weight_kg <= 8:
    price_weight = 5.42
elif weight_kg <= 9:
    price_weight = 5.42
elif weight_kg <= 10:
    price_weight = 5.42
elif weight_kg <= 11:
    price_weight = 5.43 
else:
    price_weight = 5.63

print(price_weight)




shipping_price = [{"weight": 0.25, "price" : 2.18}, {"weight": 0.5 "price" : 2.32}, {"weight": 1 "price" : 2.49}]

toy_weight = 0.6

price = [ship_price["weight"] for ship_price in shipping_price if ship_price["weight"] <= toy_weight]
print(price)
Jeffrey
  • 1
  • 2
  • 1
    is there a formula for calculating `price_weight`? – Hadrian Oct 23 '20 at 15:40
  • 1
    Maybe find some ideas here: https://stackoverflow.com/questions/61030617/how-can-i-simplify-repetitive-if-elif-statements-in-my-grading-system-function – user2390182 Oct 23 '20 at 15:42
  • After the price weight is defined for the toy that value is used to calculate the shipping price / price tier. That is a later stage, for now I am trying to figure out how to do the if statement more elegantly / choosing the correct price tier. – Jeffrey Oct 23 '20 at 15:45
  • 1
    @Jeffrey are you sure the first answer @schwobaseggl linked to using `bisect` doesn't answer your question? Looks pretty bang on to me – L.Grozinger Oct 23 '20 at 15:48

1 Answers1

0

Since you only want the first value from the generator expression, you don't want a list at all. Just use next to pull the first value:

>>> shipping_price = [
...     {"weight": 0.25, "price" : 2.18},
...     {"weight": 0.5, "price" : 2.32},
...     {"weight": 1, "price" : 2.49}
... ]
>>> toy_weight = 0.6
>>> next(sp["price"] for sp in shipping_price if sp["weight"] >= toy_weight)
2.49

I'd use tuples for this rather than dictionaries. Possibly NamedTuples if you have a lot of fields and want to give them names, but for two values I'd just use a plain old tuple like this:

>>> weights_and_prices = [(0.25, 2.18), (0.5, 2.32), (1, 2.49)]
>>> toy_weight = 0.6
>>> next(wp[1] for wp in weights_and_prices if wp[0] >= toy_weight)
2.49

Expand the weights_and_prices tuple list as needed (i.e. with all the remaining weight/price values from your original if/elif chain).

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • 2
    Shouldn't an item that weighs 0.6 be priced at 2.49, not 2.18? – jarmod Oct 23 '20 at 15:50
  • I guess; I was just going off their example code and paring it down. Flipping the comparator makes it work the way you describe. :) – Samwise Oct 23 '20 at 15:53
  • @Samwise This doesn't answer the question at all. The OP wants to eliminate the block of if-statements. – ekhumoro Oct 23 '20 at 15:57
  • They're replaced by the generator. OP's question is confusingly phrased; the second part of code is their attempt at doing this for a subset of the data. I'm just expanding on that part of their code to make it accomplish what they asked for. Copying and pasting all the values from their first part of the code is not necessary to demonstrate the concept. :) – Samwise Oct 23 '20 at 15:59
  • Just to clarify. I did it properly with the if statement code, but I want to replace that with cleaner code if possible. It is more about the idea of how better to solve the problem than the values that are there. – Jeffrey Oct 23 '20 at 20:13