【问题标题】:Appending to a list in python throws an error在python中附加到列表会引发错误
【发布时间】:2016-12-05 19:16:19
【问题描述】:

我对 Python 还很陌生,我想做的是以下几点:

  1. 读取文件
  2. 将元素添加到字典中的每一行
  3. 如果键已经存在,则将它们的键值放入列表中,并将新值附加到列表中。
  4. 用新的值列表更新字典

这是我的代码:

jobChangeMap=dict() # Maps the changed job name. Format will be      jobset,originaljob,jobNumber:jobset,changedjob,jobnumber
jobValues = []

if(not jobsetName in jobsetJobMap.keys()):
    logger.debug("{0} not found as a key. Adding key and value pair".format(jobsetName))
    jobsetJobMap.update({jobsetName:jobName+","+jobNumber})
    logger.debug(jobsetJobMap)
else:
    jobValues = []
    jobValues[:]=[]
    logger.debug("{0} already found as a key. Getting list of values for key".format(jobsetName))
    jobValues=jobsetJobMap[jobsetName]
    logger.debug("Number of values for {0} is {1}".format(jobsetName,jobValues.count))
    logger.debug(jobsetJobMap)
    if(not jobName in jobValues):
        myJobName=jobName+","+jobNumber
        logger.debug("Size before adding: {0}".format(len(jobValues)))
        jobValues.append(myJobName)

这是引发以下错误的行:

File "D:\Git-Python\MountSophie-Conversion\jmoConversion\JMOExtract.py", line 163, in createJobMap
    jobValues.append(myJobName)
AttributeError: 'str' object has no attribute 'append'

为什么 Python 抱怨 jobValues 是一个 str 对象,即使我将它明确定义为类型列表?

【问题讨论】:

  • 随后你有jobValues=jobsetJobMap[jobsetName],所以之前的jobValues = [] 是无关紧要的。
  • 您已通过此语句将jobValues 的类型更改为str - jobValues=jobsetJobMap[jobsetName]
  • @khelwood - 我需要将值放入列表中。我认为这是获取键值列表的代码。不是这样吗?
  • jobValues.append(jobsetJobMap[jobsetName]) 会将字符串添加到您现有的列表中。 jobValues = [jobsetJobMap[jobsetName]] 将创建一个新列表并包含字符串并将其分配给您的变量。 jobValues=jobsetJobMap[jobsetName] 将用=(字符串)右侧的内容替换当前变量(列表)中的任何内容。
  • @JohnSquarry 请不要通过回滚我们的改进来破坏您的问题。

标签: python list


【解决方案1】:

根据这一行,jobsetJobMap 的值似乎是字符串:

jobsetJobMap.update({jobsetName:jobName+","+jobNumber})

这将使用新字符串 jobName+","+jobNumber 覆盖条目 jobsetJobMap[jobsetName],您稍后会在此行中检索并设置为 jobValues 的值:

jobValues = jobsetJobMap[jobsetName]

这会用字符串覆盖之前的listjobValues,并且字符串没有.append 方法——因此会出现错误消息。

从你的变量名推断你的意图,我认为你想做这样的事情:

# (earlier initialization)
import collections
jobsetJobMap = collections.defaultdict(list)
# ...
# (later update):
    jobsetJobMap[jobsetName].append( jobName + "," + jobNumber )

这会将作业描述符附加到与 jobsetJobMap 字典中的键 jobsetName 关联的列表(如果需要,隐式创建列表)。

【讨论】:

    【解决方案2】:

    关于您遇到的错误。 @jez 回答完美地解释了它。

    您显然是 python 新手,而且您在 Java/C# 世界中生活的时间太长了。 JK。

    我为什么这么说?

    首先,您使用的变量命名约定 (CamelCase) 是 [Java/C#] 风格。你应该更喜欢 python 上的snack_case。更多信息请参考Style Guide for Python Code

    您对使用 python 进行此类程序是正确的。因为当涉及到这类问题时,python 是如此强大。但是,您并没有充分利用 python 的力量。这不应该占用这么多代码行。

    保持您的数据结构同质化。在jobsetJobMap 中,您存储的是字符串或数组。即使它们只包含一个元素,您也可能希望将它们全部保存为数组。异构数据导致更多代码,更多代码等于更多错误。

    我会建议更多类似的东西。

    #!/usr/bin/env python
    
    lines = ['name1,1', 'name2,2', 'name1,3', 'name2,1', 'name3,1', 'name3,1']
    
    jobs_map = {}
    
    for line in lines:
        [name, number] = line.split(',', 1)
        if name in jobs_map:
            jobs_map[name].append("%s,%s" % (name, number))
        else:
            jobs_map[name] = ["%s,%s" % (name, number)]
    

    【讨论】:

    • 是的,你是对的。我在 c# 世界里待得太久了......我的问题,我没有很好地解释,是这样的:数据结构应该是一个字典格式,键:ListofValues。如果当我通读文件时,我发现密钥存在,那么我需要附加到现有的值列表中。如果键存在并且值也存在于值列表中,那么我正在使新值唯一,然后我需要将其添加回键的值列表中。不幸的是,正如您所注意到的,我对 Python 很陌生。不知道如何在 python 中解决它:-(
    • 对于投反对票的人来说,您可能是这方面的专家。我不是
    • 我认为您的代码仍然很复杂。所有那些 if/else 语句都不正确。您可以发布所有代码,甚至是您从文件中读取的部分。因为我无法完全理解您的代码的目的。
    • 是否有您希望我将其发送到的电子邮件地址?还是就在这里?
    【解决方案3】:

    我想我找到了解决这个问题的方法。它可能不是最聪明的代码,但它是我对 Python 解决方案的尝试

    if(not jobsetName in jobsetJobMap.keys()):
                        jobValues = []
                        myNewJobName=jobName+","+jobNumber
                        jobValues.append(myNewJobName)
                        logger.debug("{0} not found as a key. Adding key and value pair".format(jobsetName))
                        jobsetJobMap.update({jobsetName:jobValues})
                        logger.debug(jobsetJobMap)
                    else:
                        jobValues = []
    
                        logger.debug("{0} already found as a key. Getting list of values for key".format(jobsetName))
                        jobValues=jobsetJobMap.get(jobsetName) # Get list of values associated with the key.
    
    
                        logger.debug(jobsetJobMap)
                        if(not jobName in jobValues):
                            myJobName=jobName+","+jobNumber
                            logger.debug("Size before adding: {0}".format(len(jobValues)))
                            jobValues.append(myJobName)
                            jobsetJobMap.update({jobsetName:jobValues})
    
                        else:
                            jobCount=jobValues.count(jobName)
                            logger.debug("Job {0} already exists in the list. Adding a unique name")
                            newJobName=jobName+".M"+jobCount+","+jobNumber
                            logger.debug("{0} changed to {1}".format(jobName,newJobName))
                            jobChangeMap.update({jobsetName+","+jobName+","+jobNumber:jobsetName+","+newJobName+","+jobNumber})
                            jobValues.append(newJobName)
                            jobsetJobMap.update({jobsetName: jobValues})
    

    【讨论】:

    • 感谢@jez 和 Abdelhakim Akodadi 为我指明了正确的方向!。如果这太复杂而无法实现它的功能,请再次告诉我。
    猜你喜欢
    • 2016-01-16
    • 1970-01-01
    • 2013-08-15
    • 2014-07-01
    • 1970-01-01
    • 2015-12-24
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多