Reputation: 43
There is a problem is have to solve here it is
You are given a string of numbers between 0-9. Find the average of these numbers and return it as a floored whole number (ie: no decimal places) written out as a string. Eg:
"zero nine five two" -> "four"
here is my code
from math import floor
x = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight','nine']
def average_string(s):
s = s.split(' ')
dnumber = {k: i for i, k in enumerate(x)}
converter = [l for n, l in dnumber.items() for i in s if n == i]
floorN = floor(sum(converter) - len(converter))
for i,k in dnumber.items():
if k == floorN:
return i #<--is this the problem?
print(average_string("zero nine five two"))
why is it returning None is there another way compare and return a value from a dict.items()
Upvotes: 2
Views: 1225
Reputation: 79288
To reduce the number of foo-loops
to be used, including sum
you can do:
def average_string(s):
x = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight','nine']
total = 0
for i,j in enumerate(x):
if j in s:
total += i+1
return total//len(s.split())
If you include the zero
in the list, then your order becomes 0(n)
by doing the following:
def average_string(s):
x = ['zero','one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight','nine']
total = 0
count = 0
for i,j in enumerate(x):
if j in s:
total += i
count += 1
return total//count
Upvotes: 0
Reputation: 140246
The result should be "four". But your average formula is wrong: you have to sum then divide not subtract.
So when you're looping (what a strange idea?) in the dictionary, you don't find the value, so you reach the end of the function and python returns None
in that case.
So fix the formula, then instead of flooring, convert back to index using integer division so everything is kept as integers, and use x
to convert to letter-as-string:
def average_string(s):
s = s.split(' ')
dnumber = {k:i for i, k in enumerate(x)}
converter = [l for n, l in dnumber.items() for i in s if n == i]
floorN = sum(converter) // len(converter)
return x[floorN-1]
as an aside, you could put the dnumber
computation out of the function, since it doesn't depend on the passed parameters (faster if there are many calls), also you don't really use the dictionary as efficiently as it should be. A clear rewrite would be:
x = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight','nine']
dnumber = {k:i for i, k in enumerate(x)}
def average_string(s):
converter = [dnumber[w] for w in s.split()]
floorN = int(sum(converter) / len(converter))
return x[floorN]
now that I've put zero
in the dictionary, I'm able to convert from letter to digit and back, without any loop, to benefit from fast dict/list lookup.
Upvotes: 1