Karan Thakkar
Karan Thakkar

Reputation: 1027

How to add odd numbers from a list in python?

Write a function that accepts a list of integers as parameter. Your function should return the sum of all the odd numbers in the list. If there are no odd numbers in the list, your function should return 0 as the sum.

def odd_numbers (my_list):
    total = 0
    count = 0
    for number in my_list:
        if (number % 2 == 1):
            total = total + number 
        else:
            count = count + 1
    if (number == count):
        return (0)
    else:
        return (total)

#Main Program

my_list = []
n = int(input("Enter the maximum length of a list: "))
while (len(my_list) < n):
    item = input ("Enter integer value to the list: ")
    my_list.append(item)
print ("This is your list: ", my_list)
result = odd_numbers(my_list)
print (result)

This is my program. When I execute it, there's an error at first if condition in the function odd_numbers and when I call the function from my main program. I can't understand the nature of this error. It just states that

TypeError: not all arguments converted during string formatting

Upvotes: 1

Views: 13269

Answers (6)

Joao Luiz Cadore
Joao Luiz Cadore

Reputation: 2732

Try this code:

def read_int(msg):
    n = None
    while n is None:
        try:
            n = int(input(msg))
        except ValueError:
            print("You should enter only integer values!")
    return n


def odd_numbers (my_list):
    total = 0
    count = 0
    for number in my_list:
        if (number % 2 == 1):
            total = total + number 
        else:
            count = count + 1
    if (number == count):
        return (0)
    else:
        return (total)

#Main Program

my_list = []
n = read_int("Enter the maximum length of a list: ")

while (len(my_list) < n):
    item = read_int("Enter integer value to the list: ")
    my_list.append(item)


print ("This is your list: ", my_list)
result = odd_numbers(my_list)
print (result)

Upvotes: 2

elm
elm

Reputation: 20415

A for comprehension brings a concise syntax; for completeness consider also this recursive function,

def f(xs):
    if xs == []: 
        return 0
    else: 
        v = 0 if xs[0] % 2 == 0 else xs[0]
        return v + f(xs[1:])

This function terminates as it decreases the list by one element at each recursive call up to the empty list.

Upvotes: 1

Vivek Sable
Vivek Sable

Reputation: 10213

A. raw_input return value which data type is string, so need Type Casting

>>> item = raw_input("Enter Number:")
Enter Number:2
>>> type(item)
<type 'str'>
>>> item = int(raw_input("Enter Number:"))
Enter Number:4
>>> type(item)
<type 'int'>
>>> 

B. Exception Handling during Type Casting: If user enter any other character from digit then above code will raise ValueError exception which need to handle.

e.g.

>>> item = int(raw_input("Enter Number:"))
Enter Number:w
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'w'

Demo with exception handling:

>>> try:
...     item = int(raw_input("Enter Number:"))
... except ValueError:
...     print "Enter only digits."
... 
Enter Number:rt
Enter only digits.

C. Related to actual algorithm

a. No need of count variable logic.

b. No need of if loop during value return.

c. Best to change function number to sumOfOddNumbers i.e. more meaningful.

Demo :

def sumOfOddNumbers (numbers_list):
    total = 0
    for number in numbers_list:
        if (number % 2 == 1):
            total += number 

    return total

D. Use list comprehension, sum method, lambda function as mention in other answers

E. Time to run following code:

lst = range(10000000)

def sum_of_odd_numbers1():
    return sum((i*(i%2) for i in lst), 0)

def sum_of_odd_numbers2():
    return sum((i for i in lst if i%2), 0)

def sum_of_odd_numbers3():
    return sum(filter(lambda x: x%2, lst), 0)

def sumOfOddNumbers ():
    total = 0
    for number in lst:
        if (number % 2 == 1):
            total += number 

    return total

import time
start_time = time.time()
sum_of_odd_numbers1()
end_time = time.time()
print "Timing of sum_of_odd_numbers1:", end_time - start_time

start_time = time.time()
sum_of_odd_numbers2()
end_time = time.time()
print "Timing of sum_of_odd_numbers2:", end_time - start_time

start_time = time.time()
sum_of_odd_numbers3()
end_time = time.time()
print "Timing of sum_of_odd_numbers3:", end_time - start_time

start_time = time.time()
sumOfOddNumbers()
end_time = time.time()
print "Timing of sumOfOddNumbers:", end_time - start_time

respective output:

vivek:~$ python /home/vivek/workspace/vtestproject/study/timer.py
Timing of sum_of_odd_numbers1: 2.4171102047
Timing of sum_of_odd_numbers2: 1.73781108856
Timing of sum_of_odd_numbers3: 2.09230113029
Timing of sumOfOddNumbers: 1.42781090736

Upvotes: 2

fredstban
fredstban

Reputation: 66

try this:

def odd_number(list_):
  odd_nums = [nums for nums in list_ if nums % 2 != 0]
  if odd_nums:
    return sum(odd_nums)
  else:
    return 0

my_list = range(10)

print (odd_number(my_list))

Upvotes: 1

Hugh Bothwell
Hugh Bothwell

Reputation: 56634

The problem is: when you do

item = input("Enter integer value to the list: ")

item is a string. It gets stored in a list, passed to odd_numbers(), and when you get to

if (number % 2 == 1):

when it sees str % something it tries to apply old-style string formatting (for example, "%04d" % 3 results in "0003"). But your string doesn't have any format specifiers (no "%" characters), so it complains that there are more arguments than there are places to put them ;-)

To avoid this, make sure you convert the string to a number, ie

item = int(input("Enter integer value to the list: "))

A somewhat hacky solution:

def sum_of_odd_numbers(lst):
    return sum((i*(i%2) for i in lst), 0)

or a more readable one,

def sum_of_odd_numbers(lst):
    return sum((i for i in lst if i%2), 0)

or a functional equivalent,

def sum_of_odd_numbers(lst):
    return sum(filter(lambda x: x%2, lst), 0)

Upvotes: 3

Selcuk
Selcuk

Reputation: 59184

Your code would work with Python 2.7 but not Python 3.x, since the input function returns a string in Python 3. Change

item = input("Enter integer value to the list: ")

to

item = int(input("Enter integer value to the list: "))

That being said, you can also shorten your function as:

def odd_numbers (my_list):
    total = 0
    for number in my_list:
        if (number % 2 == 1):
            total = total + number 
    return (total)

You can also use the generator method provided by @minitoto to optimize even more after you learn about list comprehensions/generator expressions in Python.

Upvotes: 1

Related Questions