[英]Python nested update cursor with nested dictionary. There's got to be an easier way
I've created a nested dictionary calling values from a table, and I need to update the attribute table for a feature class using that data. 我创建了一个嵌套的字典,用于从表中调用值,并且需要使用该数据为要素类更新属性表。 I have it working with two hard-coded fields as a test, but I need to figure out how to automate getting the length of
featFields
and using that to indicate the index position for each field to be updated. 我将它与两个硬编码字段一起工作作为测试,但我需要弄清楚如何自动获取
featFields
的长度,并使用它来指示要更新的每个字段的索引位置。 So, instead of hard-coding row[1]
, row[2]
, etc. and 'LOCDESC'
and 'RIMELEV'
, I'd be using a variable to step through index positions for each one. 因此,我不是使用硬编码
row[1]
, row[2]
等以及'LOCDESC'
和'RIMELEV'
,而是使用一个变量来逐步遍历每个索引的位置。
I am working in Python. 我正在使用Python。 End goal is a toolbox for use in ArcMap 10.2 or 10.3.
最终目标是在ArcMap 10.2或10.3中使用的工具箱。
import arcpy
arcpy.env.workspace = r"C:/SARP10/MACP_Tool"
#Define fields to update and the field to use as join field
Table = "Test2.csv"
Input = "Test.gdb/MHs"
csvFields = ['Location_Details', 'Elevation']
featFields = ['LOCDESC', 'RIMELEV']
csvKey = "Manhole_Number"
featKey = "FACILITYID"
csvFields.insert(0, csvKey)
featFields.insert(0, featKey)
print csvFields
#Create dictionary to store values from the update table
UpdateDict = {}
#Iterates through the values in the table and stores them in UpdateDict
with arcpy.da.SearchCursor(Table, csvFields) as cursor:
for row in cursor:
UpdateDict[row[0]] = dict(zip(featFields[1:], row[1:]))
print UpdateDict
MHNum = len(UpdateDict) # gets # of MHs to be updated
MHKeys = UpdateDict.keys() # gets key values, i.e. MH numbers
print "You are updating fields for the following {} manholes: {}".format(MHNum, MHKeys)
#Iterates through feature class attribute table and updates desired attributes
with arcpy.da.UpdateCursor(Input, featFields) as cursor:
i = 0
z = 0
for row in cursor:
i += 1
for f in UpdateDict.keys():
if f == row[0]:
row[1] = UpdateDict.values()[z]['LOCDESC']#uses counter and subdict key to call correct value
row[2] = UpdateDict.values()[z]['RIMELEV']#uses counter and subdict key to call correct value
cursor.updateRow(row)
z +=1 #counter keeps track of rows and provides index location for dictionary
print "Updating {} of {} manholes in this submittal: {}.".format(z, MHNum, f)
else:
pass
print "Updated {} of {} rows.".format(MHNum, i)
print "Script completed."
Since the (currently hard-coded) iteration of row[n]
steps through the values of featFields
, you can set up an for loop that iterates through them both, something like: 由于
row[n]
的(当前为硬编码)迭代逐步遍历了featFields
的值, featFields
您可以设置一个for循环来对它们进行迭代,如下所示:
if f == row[0]:
# loop set by length of featFields list
for j in range(0, len(featFields) - 1):
row[j + 1] = UpdateDict.values()[z][featFields[j]]
cursor.updateRow(row)
# etc.
Note the "offset" -- row[1]
should be using featFields[0]
and so on -- that needs to be accounted for. 请注意,“偏移”
featFields[0]
row[1]
应该使用featFields[0]
,依此类推-需要解决。
The problem was with accessing the right fields in the data dictionary. 问题在于访问数据字典中的正确字段。 Final code accesses a list of outer keys and a list of inner key: value pairs with a variable (z) set to keep the index number equal in both lists.
最终代码访问一个外键列表和一个内键列表:设置了变量(z)的值对,以使两个列表中的索引号保持相等。 Thanks for your help, @Erica!
感谢您的帮助,@ Erica!
Here's what works: 这是有效的方法:
import arcpy
arcpy.env.workspace = r"C:/SARP10/MACP_Tool"
#Defines fields to update and the field to use as join field
Table = "Test2.csv"
Input = "Test.gdb/MHs"
csvFields = ['Location_Details', 'Elevation', 'Rim_to_Invert', 'Rim_to_Grade', 'Cover_Size', 'Wall_Material', 'Wall_Diam', 'Wall_Lining_Interior', 'Photo2_Link', 'MH_InspectReportLink'] #update table fields
featFields = ['LOCDESC', 'RIMELEV', 'RIMTOINVERT', 'RIMTOGRADE','COVERSIZE','WALLMAT','DIAMETER','LINERTYPE','HYPERLINK_PHOTO2','HYPERLINK_RPT']#fc field names
csvKey = "Manhole_Number"
featKey = "FACILITYID"
csvFields.insert(0, csvKey)
featFields.insert(0, featKey)
print "Your table contains the following fields to be updated: {}\n".format(str(csvFields))
#Process: Create dictionary to store values from the update table, iterate through values and store in UpdateDict
UpdateDict = {}
with arcpy.da.SearchCursor(Table, csvFields) as cursor:
for row in cursor:
UpdateDict[row[0]] = dict(zip(featFields[1:], row[1:]))
## debug print "You have created update dictionary 'UpdateDict': \n{}\n\n".format(UpdateDict)
MHNum = len(UpdateDict) # gets # of MHs to be updatedMHKeys = sorted(UpdateDict.keys()) # gets key values, i.e. MH numbers
MHKeys = UpdateDict.keys() #calls outer keys (MH numbers, which are join values) into a list of keys
MHVals = UpdateDict.values()#calls inner nested key:value pairs to a list
##debug print "Dictionary keys: {}\n\n Dictionary values: {}\n\n".format(str(MHKeys),str(MHVals))
print "You are updating fields for the following {} manholes: {}".format(MHNum, str(MHKeys))
#Process: Iterates through feature class attribute table and updates desired attributes
with arcpy.da.UpdateCursor(Input, featFields) as curs:
i = 0 #attribute table row counter
for row in curs:
i += 1
for f in MHKeys:
if f == row[0]:
z = MHKeys.index(f)#get index location in MHKeys
for y in range(0,len(featFields)-1):
row[y+1] = MHVals[z][featFields[y+1]]#use z to pull corresponding value in MHVals to correct key in MHKeys
print "Current MH: {} \nUpdating Values: {} \n\n".format(f, UpdateDict.values()[z])
curs.updateRow(row)
else:
pass
print "Updated {} of {} rows.".format(MHNum, i)
print "Script completed."
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.