Mike
Mike

Reputation: 4405

Adding Multiple Values to a Single Key in Python Dictionary

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

Upvotes: 0

Views: 2276

Answers (3)

Marius
Marius

Reputation: 60060

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.

Upvotes: 3

Daniel Roseman
Daniel Roseman

Reputation: 599450

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.

Upvotes: 3

ndpu
ndpu

Reputation: 22561

Use collections.defaultdict:

from collections import defaultdict

definitionQuery_Dict = defaultdict(list)
# ...

Upvotes: 2

Related Questions