0

Python dictionaries really have me today. I've been pouring over stack, trying to find a way to do a simple append of a new value to an existing key in a python dictionary adn I'm failing at every attempt and using the same syntaxes I see on here.

This is what i am trying to do:

#cursor seach a xls file
definitionQuery_Dict = {}

for row in arcpy.SearchCursor(xls):

    # set some source paths from strings in the xls file
    dataSourcePath = str(row.getValue("workspace_path")) + "\\" + str(row.getValue("dataSource"))
    dataSource = row.getValue("dataSource")

    # add items to dictionary. The keys are the dayasource table and the values will be definition (SQL) queries. First test is to see if a defintion query exists in the row and if it does, we want to add the key,value pair to a dictionary.
    if row.getValue("Definition_Query") <> None:

        # if key already exists, then append a new value to the value list
        if row.getValue("dataSource") in definitionQuery_Dict:
            definitionQuery_Dict[row.getValue("dataSource")].append(row.getValue("Definition_Query"))
        else:
            # otherwise, add a new key, value pair
            definitionQuery_Dict[row.getValue("dataSource")] = row.getValue("Definition_Query")

I get an attribute error:

AttributeError: 'unicode' object has no attribute 'append'

But I believe I am doing the same as the answer provided here

I've tried various other methods with no luck with various other error messages. i know this is probably simple and maybe I couldn't find the right source on the web, but I'm stuck. Anyone care to help?

Thanks, Mike

3 Answers 3

3

The issue is that you're originally setting the value to be a string (ie the result of row.getValue) but then trying to append it if it already exists. You need to set the original value to a list containing a single string. Change the last line to this:

definitionQuery_Dict[row.getValue("dataSource")] = [row.getValue("Definition_Query")]

(notice the brackets round the value).

ndpu has a good point with the use of defaultdict: but if you're using that, you should always do append - ie replace the whole if/else statement with the append you're currently doing in the if clause.

Sign up to request clarification or add additional context in comments.

1 Comment

Ughh...I knew I needed something like this. To set the values to a list. I think I jsut looked at too many examples and then I confused myself. This is exactly what I need. Thanks!
3

Your dictionary has keys and values. If you want to add to the values as you go, then each value has to be a type that can be extended/expanded, like a list or another dictionary. Currently each value in your dictionary is a string, where what you want instead is a list containing strings. If you use lists, you can do something like:

mydict = {}
records = [('a', 2), ('b', 3), ('a', 4)]

for key, data in records:
    # If this is a new key, create a list to store
    # the values
    if not key in mydict:
        mydict[key] = []
    mydict[key].append(data)

Output:

mydict
Out[4]: {'a': [2, 4], 'b': [3]}

Note that even though 'b' only has one value, that single value still has to be put in a list, so that it can be added to later on.

Comments

2

Use collections.defaultdict:

from collections import defaultdict

definitionQuery_Dict = defaultdict(list)
# ...

1 Comment

So, just import defaultdict and then change my variable from definitionQuery_Dict = {} to definitionQuery_Dict = defaultdict(list)? If so, I am still gettting the same error....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.