2016-12-05 3 views
-2

Я довольно новыми для Python и то, что я пытаюсь сделать, это следующее:добавление в список в 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, хотя я явно определил его как список типов?

+1

Впоследствии вы имеете 'jobValues ​​= jobsetJobMap [jobsetName]', поэтому ранее 'jobValues ​​= [] 'не имеет значения. – khelwood

+1

Вы изменили тип 'jobValues' на' str' через этот оператор - 'jobValues ​​= jobsetJobMap [jobsetName]'. –

+0

@khelwood - Мне нужно получить значения в списке. Я думал, что это код, чтобы получить список значений для ключа. Разве это не так? –

ответ

0

Значение jobsetJobMap кажется строки по этой линии:

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

Это перезаписывает запись jobsetJobMap[jobsetName] с новой строкой, jobName+","+jobNumber который вы позже извлекать и устанавливать в качестве значения jobValues в этой строке:

jobValues = jobsetJobMap[jobsetName] 

Это перезаписывает предыдущее list значение jobValues со строкой, и строки не имеют .append метод, следовательно, ваше сообщение об ошибке.

Выведение свое намерение от ваших имен переменных, я думаю, что вы хотите сделать что-то вроде:

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

Это добавляет дескриптор задания в списке (неявно создание списка, если это необходимо), что связано с ключ jobsetName в словаре jobsetJobMap.

0

Об ошибке, которую вы имели. Ответ @jez объясняет это отлично.

Вы, очевидно, новичок в python, и вы слишком долго жили в мире Java/C#. JK.

Почему я говорю это?

Ну, в первую очередь, соглашение об именах переменных, которое вы используете (CamelCase), - это стиль [Java/C#]. Вы должны предпочесть snack_case на python. Дополнительную информацию см. В разделе 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)] 
+0

да, вы правы. Я слишком долго был в мире C# ... моя проблема, о которой я не очень хорошо объяснил, заключается в следующем: структура данных должна быть словарем формата, ключ: ListofValues. Если когда я прочитаю файл, я обнаружил, что ключ существует, тогда мне нужно добавить существующий список значений. если ключ существует и значение также существует в списке значений, то я делаю новое значение уникальным, а затем мне нужно добавить его обратно в список значений для ключа. К сожалению, я очень новичок в Python, как вы заметили. не знаю, как его решить в python :-( –

+0

Также для людей, которые имеют downvoted, вы, вероятно, эксперты в этом. Я не –

+0

Я думаю, что ваш код все еще сложный. Все эти if/else утверждения не правы Можете ли вы опубликовать весь свой код, даже часть, в которой вы читаете файл, потому что я не могу полностью понять цель вашего кода. –

0

Я думаю, что нашел способ работать через это. он не может быть умным код, но это моя попытка решения в 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}) 
+0

Спасибо @jez и Abdelhakim Akodadi за то, что указали мне в правильном направлении! Позвольте мне узнать еще раз, если это слишком сложно для достижения того, что он делает. –

Смежные вопросы