0

I'm having trouble iterating through a dictionary's keys' values and performing mathematical operations where each key has a different number of values:

fruits  = {
"banana": [4,5],
"apple": 2,
"orange":1.5,
"pear": 3   
}

What I'd like from the code (i.e., my ideal production):

banana [8, 10]
apple 4
orange 3.0
pear 6

I want to times (*) each integer within each key by 2. I've tried the following but I am unable to get it right:

for fruit, price in fruits.items():
    print(fruit, price*2)
    for i in price:
        print(fruit, i*2)

...But to no avail: this produces:

banana [4, 5, 4, 5]
banana 8
banana 10
apple 4

Okay, so I tried this:

for fruit, price in fruits.items():
#print(type(price))

if len(fruit)>0:
    print(price*2)

elif len(fruit) == 0:
    print(price*2)

To which it produced this:

[4, 5, 4, 5]
4
3.0
6

Is this even possible?

Any answers will be much appreciated.

Kind regards,

A. Smith

  • 1
    What happens when you run this code and how does it differ from your expected result? – JacobIRR Jun 18 '18 at 22:52
  • can you show us what you would _like_ from that code? – Michael Jun 18 '18 at 22:53
  • Your problem is that `price` is sometimes an integer, sometimes a float, and sometimes a list. The float/int thing is not a big deal (multiplying by 2 works for both cases) but figuring out when you have list requires some care. See if this answer helps: https://stackoverflow.com/questions/1835018/how-to-check-if-an-object-is-a-list-or-tuple-but-not-string – Paul Cornelius Jun 18 '18 at 23:02

2 Answers2

0

This code runs, unlike your code... but I'm not sure this is fully satisfying what you're trying to do. Your code would raise TypeError: 'int' object is not iterable so importing collections and checking that your item is iterable does this safely:

import collections
fruits = {
    "banana": [4, 5],
    "apple": 2,
    "orange": 1.5,
    "pear": 3
}

for fruit, price in fruits.items():
    if isinstance(price, collections.Iterable):
        for i in price:
            print(fruit, i * 2)
    else:
        print(fruit, price * 2)

Result

banana 8
banana 10
apple 4
orange 3.0
pear 6
JacobIRR
  • 8,545
  • 8
  • 39
  • 68
0

If lists are the exception rather than the rule, then you can use try / except as follows:

def multiplier(x, n):
    try:
        return float(x)*n
    except TypeError:
        return [i*n for i in x]

res = {k: multiplier(v, 2) for k, v in fruits.items()}

print(res)

{'banana': [8, 10], 'apple': 4.0, 'orange': 3.0, 'pear': 6.0}

Alternatively, you can use collections.Iterable if you wish to test explicitly for iterables:

from collections import Iterable

def multiplier(x, n):
    return [i*n for i in x] if isinstance(x, Iterable) else x*n

Then, for your formatted output, you can iterate your result:

for k, v in res.items():
    print(k, v)

banana [8, 10]
apple 4.0
orange 3.0
pear 6.0
jpp
  • 159,742
  • 34
  • 281
  • 339