【问题标题】:Assigning points based on length of list of list根据列表列表的长度分配点
【发布时间】:2018-05-05 08:12:08
【问题描述】:

我试图弄清楚如何根据列表中剩余的项目数将数字分配给列表中的某个点。
例如:

def prizeHandout(prizeWinners):
    for x in range(len(prizeWinners)):
        if len(prizeWinners) == 24:
            prizeWinners[x][2] = (int(prize[0]))
        elif len(prizeWinners) == 12:
            prizeWinners[x][2] = (int(prize[1]))
        elif len(prizeWinners) == 6:
            prizeWinners[x][2] = (int(prize[2]))
    print(prizeWinners)  

我有一个全局变量 'prize',它是一个包含奖品的列表 [10, 20, 30,....]
'prizeWinners' 位于此格式的列表列表中[[ab, 2, 0], [ba, 5, 0], [aa, 12, 0], .....]
在 'prizeWinners' 变量中,'prize' 的赋值应该添加到当前空间 [2] 并添加到前一个数字(如果有的话)。
似乎无法正常工作。
任何帮助将不胜感激,谢谢:)

def prizesFunction():
    with open('prizes.csv', 'r') as f:
        reader = csv.reader(f)
        prizePoints = list(reader)
        first= [i[1] for i in prizePoints]
        second = [i[0] for i in prizePoints]
        third = [i[2] for i in prizePoints]
        fourth = [i[3] for i in prizePoints]

    choice = input('Enter your choice [0-4] : ')
    choice = int(choice)
    global prize
    if choice == 1:
        prize = first
        return prize
    elif choice == 2:
        prize =second
        return prize
    elif choice == 3:
        prize = third
        return prize
    elif choice == 4:
        prize = fourth
        return prize

【问题讨论】:

  • 你试过什么?会发生什么,您会期待什么?
  • 嗨,先生Carnivore,我希望第一个输出是 [[ab, 2, 10], [ba, 5, 10], .....] 目前我是出现错误 'TypeError: 'str' object does not support item assignment' 并尝试更改变量的类型,但由于它们是列表,我不确定要尝试将它们更改为什么。
  • 请向我们展示导致问题的确切代码(仅相关部分!)以及问题中的确切错误消息(您可以编辑它!)
  • 如果有帮助的话,我刚刚上传了一些!

标签: python arrays list loops if-statement


【解决方案1】:

好的,既然你从中得到了一些东西,我会再次分解它。尽管我很确定我仍然不明白,因此无法解决您的问题。但是,我们可以清理一下。

我还是不喜欢全局变量。你现在在你的代码中做你想做的事,但我告诉你global 是一个关键字,因为它只应该在特殊情况下使用。但是,由于您 return prize 并且不使用它,因此在分配之前或之后我已经用 return 值替换了全局并在函数之外添加了一个分配。同样,这是 python,而不是 C。一切都是对象,通常通过引用传递。所以东西退回就可以了,不用原地修改。

接下来引起我注意的是firstfourth 的列表推导。关于这一点的三件事,首先是它们是在with 块中定义的,这意味着如果打开“prizes.csv”时出错,它们可能是未定义的,所以我将它们初始化为一个空列表,而不是with .接下来,这个列表理解有点我们的顺序,因为first 是第二个值,second 是第一个值,所以我重新排列了它。最后,你为什么要这样做?这将生成代表输入 csv 的第 1 到第 4 列的值列表。 如果我不得不猜测,这意味着您要创建作为 CSV 列的奖品。无论如何,至少该列的前 4 行。

最后,您的问题是类型错误。这就是为什么你真的在这里。 csv.reader 的输出是str 的列表,您想要的值是int 或可能是float 值。因此,正如我上面提到的,将字符串文字读入 python 值的安全方法是使用 ast.literal_eval() 函数。这可以通过几种方式来完成。我认为你的代码中最好的地方是列表理解(我把它们留在那里只是为了这个目的)。你可以看到我在哪里添加了ast.literal_eval(),这个函数将一个字符串作为输入并解析它,就像它是python代码一样,但不执行它(使它成为eval()的“安全”替代品)这意味着当您尝试将数字相加时,您不会收到您遇到的类型错误。您收到该类型错误是因为 python 是强类型(并且是动态类型)。这意味着您不能将str 添加到int,并且它不会像JavaScript 那样自动将int 转换为str

import ast

def prizesFunction():
    first  = []
    second = []
    third  = []
    fourth = []

    with open('prizes.csv', 'r') as f:
        reader = csv.reader(f)
        prizePoints = list(reader)
        first  = [ast.literal_evel(i[0]) for i in prizePoints]
        second = [ast.literal_evel(i[1]) for i in prizePoints]
        third  = [ast.literal_evel(i[2]) for i in prizePoints]
        fourth = [ast.literal_evel(i[3]) for i in prizePoints]

    choice = input('Enter your choice [0-4] : ')
    choice = int(choice)

    if choice == 1:
        return first
    elif choice == 2:
        return second
    elif choice == 3:
        return third
    elif choice == 4:
        return fourth

prize = prizesFunction()

好的,这应该会有所帮助。还有,是不是很好看?当你在写 python 并且它开始看起来很乱时......你可能没有在 python 上做它。 import this

【讨论】:

  • 哇,再次感谢您的精彩回复,非常感谢!关于您的“您在这里做什么”问题,我试图从每一行中获得不同的奖品积分,而每列对于每个不同的运行都有不同的奖品。刚刚测试了你给我的东西,似乎一切正常,谢谢!当我加入这个网站时,我从没想过有人会像你今天这样乐于助人。花时间解释事情让我受益匪浅,我很高兴你能花时间来做这件事!
  • 任何时候。我们都在一起。
【解决方案2】:

首先,这是python,而不是C,所以你应该使用for循环

for prizeWinner in prizeWinners:

这消除了对range() 的需要。 “如果我需要知道索引怎么办,”我听到你问?好吧,在这种情况下你不需要,但如果你这样做了,pythonic 的方法是使用enumerate() 像这样

for ii,prizeWinner in enumerate(prizeWinners):

我知道这很迂腐,但让我们看看这个简单的更改对您的代码有何影响。

def prizeHandout(prizeWinners):
    for prizeWinner in prizeWinners:
        if len(prizeWinners) == 24:
            prizeWinner[2] = (int(prize[0]))
        elif len(prizeWinners) == 12:
            prizeWinner[2] = (int(prize[1]))
        elif len(prizeWinners) == 6:
            prizeWinner[2] = (int(prize[2]))
    print(prizeWinners)  

已经感觉好多了。
现在,“奖品是一个全局变量”已经不好说了。所以我们应该将它传递给函数,我们将使用默认值。
你为什么将奖品作为一个整数?我相信您有充分的理由,但如果这个原因恰好是您将str 转换为int,我建议您使用ast.literal_eval()。我正在删除它,因为它在您的其余问题中没有任何上下文。 至于将奖品添加到 PrizeWinner[2],让我们进行更改。

def prizeHandout(prizeWinners, prize=[10,20,30]):
    for prizeWinner in prizeWinners:
        if len(prizeWinners) == 24:
            prizeWinner[2] += prize[0]
        elif len(prizeWinners) == 12:
            prizeWinner[2] += prize[1]
        elif len(prizeWinners) == 6:
            prizeWinner[2] += prize[2]
    print(prizeWinners)  

我无法从您的程序中回答您为什么要通过 len(prizeWinners) 来确定奖品?我想你正在尝试做的是查看它们在数组中的索引。所以,这就是enumerate() 派上用场的地方。试穿这个尺寸;如果他们在获奖者列表的前面排在第 25 位,这将使 PrizeWinner[2] 增加 10,如果他们是第 13 位,则增加 20,如果他们是第 7 位,则增加 30。

def prizeHandout(prizeWinners, prize=[10,20,30]):
    for ii, prizeWinner in enumerate(prizeWinners):
        if   ii == 24:
            prizeWinner[2] += prize[0]
        elif ii == 12:
            prizeWinner[2] += prize[1]
        elif ii == 6:
            prizeWinner[2] += prize[2]
    print(prizeWinners)  

这就是我能说的。我希望你能按照我的步骤。

【讨论】:

  • 您好 VoNWooDSoN,首先非常感谢您的全面回答。你给我的信息正是我需要帮助我进一步学习的东西!我已经实现了您提供的代码,但我仍然收到我在上面的评论中提到的“TypeError”。我已经编辑了我的原始问题,以包含更多我想要做的事情。可以理解,您已经提供了很多帮助,但您知道这个错误的原因吗?谢谢!
猜你喜欢
  • 2013-11-26
  • 2022-11-19
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多