2016-02-12 40 views
1

編寫一個接受整數列表作爲參數的函數。你的函數應該返回列表中所有奇數的總和。如果列表中沒有奇數,你的函數應該返回0作爲總和。如何添加Python中的列表中的奇數?

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) 

這是我的程序。當我執行它時,如果函數odd_numbers中的條件和我從主程序中調用該函數時出現錯誤。我無法理解這個錯誤的性質。它只是說

TypeError: not all arguments converted during string formatting

+0

爲什麼你這樣標記'python-2.7'和'python-3.x'?你是否真的在兩個版本中遇到同樣的錯誤? – Barmar

+0

什麼是'if(number == count)'?在循環之後,'number'是列表中的最後一個元素,而'count'是偶數的個數。 'number == count'如何告訴你列表中沒有奇數? – Barmar

+0

@Barmar他打算寫'if(count == 0)',但即使如此,'total'總是零,無論如何都是多餘的。 – Selcuk

回答

3

的問題是:當你做

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

item是一個字符串。它被存儲在一個列表,傳遞到odd_numbers(),當你到

if (number % 2 == 1): 

當它看到str % something它試圖(以"0003"例如,"%04d" % 3結果)申請舊式的字符串格式化。但是你的字符串沒有任何格式說明符(沒有"%"字符),所以它抱怨說有更多的參數比有地方把它們;-)

爲了避免這種情況,請確保您將字符串轉換爲數量,即

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

一種略爲哈克溶液:

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

或更可讀的一個,

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

或功能等同物,

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

很好,Upvoted for'sum((i *(i%2)for i in lst),0)'。 –

+0

這絕對是一個聰明的方法,但我認爲'filter - > sum'是最好的方式。此外,我在手機上,但我認爲'sum'的默認第二個參數是0,所以可以省略。具有諷刺意味的是,我認爲生成器方法會最快,因爲它避免了乘法和函數調用。 –

+0

根據性能正常'for'循環,'if'循環內部,然後將總數加起來更快,因爲在列表理解中我們創建列表並且在'sum'方法中再次迭代列表以進行加法。 –

1

您的代碼將使用Python 2.7,但不Python的3.x的工作,因爲input功能在Python 3.更改返回一個字符串

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

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

也就是說,你也可以縮短你的功能:

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

您還可以使用@minitoto提供的生成器方法在Python中瞭解列表推導/生成器表達式後進一步優化。

1

嘗試:

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)) 
2

A. raw_input返回值的數據類型是string,所以需要類型轉換

>>> 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.類型轉換期間的異常處理:如果用戶從數字中輸入任何其他字符,則上面的代碼將引發需要處理的異常。

例如

>>> 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' 

演示使用異常處理:

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

C. 與實際算法

一個。不需要count變量邏輯。

b。在返回值期間不需要if循環。

c。最好將功能號碼更改爲sumOfOddNumbers即更有意義。

演示:

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

    return total 

D.使用list comprehensionsum方法,lambda功能在其他的答案

提及

E. 時間運行以下代碼:

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 

各自輸出:

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 
2

試試這個代碼:

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) 
+0

歡迎來到stackoverflow upvoted。在'n = int(input(「輸入列表的最大長度:」))中執行相同的異常處理'' –

+1

謝謝Vivek,你是對的。 –

1

理解力的帶來了簡潔的語法;出於完整性考慮也是這個遞歸函數,

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

該函數會終止,因爲它降低了在每次遞歸調用到空列表列表中的一個元素。