我无法弄清楚如何在Python中创建一个调用我的函数的字典

时间:2015-02-18 14:56:45

标签: python python-3.4

  

编写一个程序,要求用户输入一些数字(正数,   否定和零)。您的程序不应该要求用户输入   固定数量的数字。它也不应该要求的数量   用户想要输入的号码。但它应该要求用户   输入几个数字并以-9999(哨兵值)结束。用户   可以按任何顺序输入数字。你的程序不应该问   用户分别输入正数和负数。

     

然后你的程序应该创建一个包含输入数字的列表(make   确保不要在此列表中包含sentinel值(-9999)和   输出列表和具有以下键值对的字典   (使用输入列表和上述功能):

我知道这是一个问题,已经在董事会上进行了3次,而且我已经尝试过复制其他示例,但我仍然会收到一个错误,指出我错过了1个必要的位置参数。我试过改变几件事而没有解决方案。我认为我的平均功能正在发挥作用,但此时我甚至都不确定。这也是我第一次在这里发布任何内容,所以我很抱歉格式不佳。以下是我的代码:

def numList(): 
    values = [] 
    while True: 
         x = int(input("Enter any amount of numbers or -9999 to quit: ")) 
         if x == -9999: break 
         values.append(x) 
    return values

def allNumAvg(values): 
    whole = [] 
    average = 0 
    for i in values: 
         whole.append(i) 
    average = sum(whole)/len(whole) 
    return average

def posNumAvg(values): 
    pos = [] 
    average = 0 
    for i in values: 
         if i > 0: 
              pos.append(i) 
              average = sum(pos)/len(pos) 
    return average

def nonPosAvg(values): 
    non = [] 
    average = 0 
    for i in values: 
         if i < 1: 
              non.append(i) 
              average = sum(non)/len(non) 
    return average

print(numList())

def store(): 
     return {'all': allNumAvg(), 'pos': posNumAvg(), 'def': nonPosAvg()}() 

print(store())

2 个答案:

答案 0 :(得分:3)

您的函数allNumAvg posNumAvgnonPosAvg都取1个参数值。你没有任何争论地打电话给他们。 allNumAvg()

尝试更改为

values = numList()

def store(): 
     return {'all': allNumAvg(values), 'pos': posNumAvg(values), 'def': nonPosAvg(values)}

答案 1 :(得分:0)

除了没有传递值并尝试调用dict之外,你在完全填充列表之前计算平均值,在你的代码中计算完成追加时循环外的平均值:

def posNumAvg(values): 
    pos = [] 
    #  average = 0 don't need to declare variable
    for i in values: 
         if i > 0: 
              pos.append(i) 
    average = sum(pos)/len(pos)  # only calculate once when done
    return average

allNumAvg中,您已经有了一个值列表,然后您创建了另一个完全相同的值列表,只需使用值本身:

def allNumAvg(values): 
    average = sum(values )/ len(values) 
    return average

您也可以使用列表推导:

def num_list():
    # "-9999" is the sentinel value which will break the loop if entered
    values = [int(i) for i in iter(lambda:input("Enter any amount of numbers or -9999 to quit: "),"-9999")]
    return values


def all_num_avg(values):
    average = sum(values) / len(values)
    return average


def pos_num_avg(values):
    pos = [x for x in values if x > 0]
    return sum(pos) / len(pos)


def non_pos_avg(values):
    non = [i for i in values if i < 1]
    return sum(non) / len(non)


values = num_list()

def store():
    return {'all': all_num_avg(values), 'pos': pos_num_avg(values), 'def': non_pos_avg(values)}

我还使用与pep-8 style guide

一致的下划线更改了您的函数名称

理想情况下,在接受用户输入时,最好使用try/except来捕获用户的错误输入:

def num_list():
    values = []
    while True:
        try:
            inp = int(input("Enter any amount of numbers or -9999 to quit: "))
            if inp == -9999:
                return values 
            values.append(int(inp))  # any input that cannot be cast will raise a ValueError which we catch and then inform the user
        except ValueError:
            print("Invalid input")
    return values

如果用户没有输入正数或负数,那么您还将获得zeroDivisionError,因此您还需要通过再次使用try / except或在列表为空时返回默认值来处理该情况,我们可以使用默认值,因为我们已经验证了输入以确保是一个数字:

 def non_pos_avg(values):
    non = [i for i in values if i < 1]
    return sum(non) / len(non) if non else 0

这一切都可以在一个函数中完成,最后更新dict并返回它:

def store():
    store_dict = {}
    values = []
    while True:
        try:
            inp = int(input("Enter any amount of numbers or -9999 to quit: "))
            if inp == -9999:
                break
            values.append(int(inp))
        except ValueError:
            print("Invalid input")
    pos = [x for x in values if x > 0]
    non = [i for i in values if i < 1] 
    # catch cases where user does not enter a mixture of pos and negative nums of break on the first iteration
    # if values etc.. will all evaluate to False for an empty list
    store_dict["all"] = sum(values) / len(values) if values else 0
    store_dict["pos"] = sum(pos) / len(pos) if pos else 0
    store_dict["def"] = sum(non) / len(non) if non else 0
    return store_dict

print(store())

因为您使用的是python3.4,我们也可以让statistics module处理平均值:

from statistics import mean

def store():
    store_dict = {}
    values = []
    while True:
        try:
            inp = int(input("Enter any amount of numbers or -9999 to quit: "))
            if inp == -9999:
                break
            values.append(int(inp))
        except ValueError:
            print("Invalid input")
    pos = [x for x in values if x > 0]
    non = [i for i in values if i < 1]
    store_dict["all"] = mean(values) if values else 0
    store_dict["pos"] = mean(pos) if pos else 0
    store_dict["def"] = mean(non) if non else 0
    return store_dict

根据你的评论,如果你想要一个dict和返回的列表,你可以返回并解压缩:

def store():
        store_dict = {}
        values = []
        while True:
            try:
                inp = int(input("Enter any amount of numbers or -9999 to quit: "))
                if inp == -9999:
                    break
                values.append(int(inp))
            except ValueError:
                print("Invalid input")
        pos = [x for x in values if x > 0]
        non = [i for i in values if i < 1]
        store_dict["all"] = mean(values) if values else 0
        store_dict["pos"] = mean(pos) if pos else 0
        store_dict["def"] = mean(non) if non else 0
        return store_dict,values

d, vals = store() # unpack 
print(d, vals)