So I am currently working on a tool that the user needs to apply a query in order to the run the tool for the queried data. I am trying to get around that by creating a blank dictionary in the script and then appending data to it. The data comes from a field in a feature class. I have never done this before but in theory it should work the same as appending to lists correct?
hubFeatures = r'hub_locations'
hubDict = {}
These are my working variables for this. The field that I want the data from to append to the dictionary is called 'NAME' in the hubFeatures FC. I was thinking of using cursors to achieve this. Unless there is an alternative approach. The idea is to then use the items in the dictionary to apply a query to the necessary layers and complete the functionality of the tool using a for loop. That part I can do. Need some assistance in setting up the dictionary.
Solved! Go to Solution.
Awesome and that doesn't interfere with my definition query that I am applying afterwards. Thank you so much for your help Blake!
Typically, no, it does not interfere. However, it can depend on how you're creating your query expression. Assuming my example valueDict above:
for i in valueDict:
expression = "NAME = '{}'".format(valueDict[i])
print expression
Output:
NAME = 'Some Name'
NAME = 'Another Name'
NAME = 'Name Example'
NAME = 'And Another'
This makes perfectly valid SQL.
However, If you do something like this:
names = tuple(valueDict.values())
expression = "NAME in{}".format(names)
print expression
Output:
NAME in(u'Some Name', u'Another Name', u'Name Example', u'And Another')
It will keep the u designation and it won't be valid SQL.
You would have to do something like:
names = tuple(str(i) for i in valueDict.values())
expression = "NAME in{}".format(names)
print expression
Output:
NAME in('Some Name', 'Another Name', 'Name Example', 'And Another')
But if you have exactly one name record in the dictionary, a single item tuple still has a comma at the end:
NAME in('Some Name',)
Which is not valid SQL.
The best would be something like:
names = ",".join("'{}'".format(i) for i in valueDict.values())
expression = "NAME in({})".format(names)
print expression
Output:
NAME in('Some Name','Another Name','Name Example','And Another')
EDIT:
Or, you could get rid of the u designation by converting row[0] to a plain string when you create the dictionary:
valueDict = {}
with arcpy.da.SearchCursor(sourceFC, ["NAME"]) as cursor:
for enum, row in enumerate(cursor):
valueDict[enum] = str(row[0])
I didn't even think of the first way you had it set up.
What I used was this:
hubFeatures = r'hub_locations'
hubDict = {}
with arcpy.da.SearchCursor(hubFeatures, 'HubName') as cursor:
for enum, row in enumerate(cursor):
hubDict[enum] = row[0]
for hub in hubDict:
valueHub = dict.get(hubDict, hub)
hubQuery = "NAME = " + "'" + str(valueHub) + "'"
hubLayer = arcpy.mapping.ListLayers(mxd, 'hub_locations')[0]
hubLayer.definitionQuery = hubQuery
On line 10, you've got the wrong syntax for get(). Should be:
valueHub = hubDict.get(hub)
But since you are iterating over the keys in the dictionary (as hub), you know the key exists so you don't need to use get()
Thank you so much Dan!
do you have them in the right order ?
r = [[1, 'a'], [2, 'b'], [3, 'c']]
valueDict = {v[0]:(v[1:]) for v in r}
valueDict
{1: ['a'], 2: ['b'], 3: ['c']}
# ---- switch it up
valueDict2 = {v[1]:(v[0]) for v in r}
valueDict2
{'a': 1, 'b': 2, 'c': 3}