How to use Update Cursor to Update Info in Empty field?

5879
8
08-19-2015 06:23 AM
fumaniwada1
New Contributor

I have a shapefile for hospitals and in the attribute table I added a  new field. My goal is to use a while loop and create a search cursor that will merge the data in the address,city,state, and zipcode fields into the new FullAddR field I successfully added. My addfield management code added the field successfully and its blank. But, I think there is something wrong with my update cursor info in the while loop. I'm not sure how to use the row.setValue to merge all the info from the different fields into one if that's even the right direction i should be going in.

#import arcpy module
import arcpy
from arcpy import env
arcpy.env.overwriteOutput = True 
# I am setting the work path 
env = r'S:\\376\\Summer15-2\\ahutche1\\lab07_data\\SectionB\\'
#I am setting the variable for the hospitals shapefile
hospitals = 'Hospitals'
#I will add a new "FULLAddR" field to the table in the hospitals shapefile
arcpy.AddField_management(env+hospitals+'.shp','FullAddR', "FLOAT",20)
#I am setting the variable for the new field.
field1 = "FullAddR"
#I am setting the variables for the fields I want to take information from
#in order to merge it into the new field I just created.
address = "ADDRESS"
city = "CITY"
state = "STATE"
zipcode = "ZIPCODE"
#I will create a cursor to update the FullAddR field
cursor1 = arcpy.UpdateCursor(env+hospitals+'.shp') #I swill set up the update cursor
row = cursor1.next()
#I will use a while loop in order to copy all the information from the
#city,state,address,and zipcode fields into the single FullAddR field. 
while row:
    row.setValue(field1,row.getValue(address,city,state,zipcode)) 
    cursor.updateRow(row)
    row = cursor1.next() 
0 Kudos
8 Replies
IanMurray
Frequent Contributor

I'm curious why are wanting to do this with a cursor and not with a geoprocessing tool such as Calculate Field.  You could concatenate together multiple string fields fairly easily with it.

Calculate Field—Help | ArcGIS for Desktop

While a cursor is a good way to do this as well, I would suggest you use the far easier to use arcpy.da.UpdateCursor.  The parameters are slightly different, but they are significantly faster and would be easier to use.

UpdateCursor—Help | ArcGIS for Desktop

Example script for using the arcpy.da.SearchCursor:

#import arcpy module  
import arcpy  
from arcpy import env  
arcpy.env.overwriteOutput = True   
# I am setting the work path   
env = r'S:\\376\\Summer15-2\\ahutche1\\lab07_data\\SectionB\\'  
#I am setting the variable for the hospitals shapefile  
hospitals = 'Hospitals'  
#I will add a new "FULLAddR" field to the table in the hospitals shapefile  
arcpy.AddField_management(env+hospitals+'.shp','FullAddR', "FLOAT",20)  
#I am setting the variable for the new field.  
field1 = "FullAddR"  
#I am setting the variables for the fields I want to take information from  
#in order to merge it into the new field I just created.  
address = "ADDRESS"  
city = "CITY"  
state = "STATE"  
zipcode = "ZIPCODE"  
# Starting cursor using with statement to automatically close after completing
with arcpy.da.UpdateCursor(env+hospitals+'.shp' , [field1 , address, city, state , zipcode]) as cursor:
  for row in cursor:
    #Making row[0] aka Full address field equal to address(row[1]) plus city(row[2]) plus state(row[3]) plus zipcode(row[4])
    row[0] = row[1] + " " + row[2] + " " + row[3] + " " + row[4]
    #updating current row values(only row[0] has changed and will be updated
    cursor.updateRow(row)

Script is untested, but between it and the help, you should get it.

fumaniwada1
New Contributor

I'm working through a python book and doing different exercises. I already know how to use calculate field but its about learning different things. Is there a way to accomplish this with a while loop?

0 Kudos
IanMurray
Frequent Contributor

Personally, I try to never use while loops unless I absolutely have to.  While its good to know how they function(since it looks like you are learning right now), for loops are much safer and can automatically loop through all my features, without telling it to go to the next row manually.

Its good you are expanding your horizons for different ways of doing things(there are about 10 ways to do anything in ArcGIS I was always told), an update cursor is definitely faster than using a geoprocessing tool, if you are doing a large amount of data processing.

For the old style cursor, you set it up correctly, I believe the issue is you need to get each field value individually and then concatentate them into one string before setting it for the new value.

while row:  
  part1 = row.getValue(address)
  part2 = row.getValue(city)
  part3 = row.getValue(state)
  part4 = row.getValue(zipcode)
  # Concatenating field values together ( str(part4) is in case zipcode is a numeric field instead of string)
  row.setValue(field1, part1 + " " + part2 + " " + part3 + " " + str(part4))
  cursor.updateRow(row)  
  row = cursor1.next()  

May not be the most pythonic way to do it, but it should function.  What workbook are you working out of?

0 Kudos
fumaniwada1
New Contributor

It's a book that my older brother created for me based on some python class he had that allows me to practice different functions and objects. I got the error that said "

Traceback (most recent call last):

  File "C:/Users/ahutche1/Desktop/lol.py", line 34, in <module>

    part1 = row.getValue(address)

AttributeError: 'list' object has no attribute 'getValue'

I edited the code you did a little because I got some errors before:

#import arcpy module
import arcpy
from arcpy import env
arcpy.env.overwriteOutput = True 
# I am setting the work path 
env = r'S:\\376\\Summer15-2\\ahutche1\\lab07_data\\SectionB\\'
#I am setting the variable for the hospitals shapefile
hospitals = 'Hospitals'
#I will add a new "FULLAddR" field to the table in the hospitals shapefile
#arcpy.AddField_management(env+hospitals+'.shp','FullAddR', "FLOAT",20)
#I am setting the variable for the new field.
field1 = "FullAddR"
address = "ADDRESS"
city = "CITY"
state = "STATE"
zipcode = "ZIPCODE"
#I will create a cursor to update the FullAddR field
cursor = arcpy.da.UpdateCursor(env+hospitals+'.shp',[field1,address,city,state,zipcode]) 
#I will use a while loop in order to copy all the information from the
 #city,state,address,and zipcode fields into the single FullAddR field.
row = cursor.next() 
while row:
#I am setting the variables for the fields I want to take information from
#in order to merge it into the new field I just created.
  part1 = row.getValue(address)  
  part2 = row.getValue(city)  
  part3 = row.getValue(state)  
  part4 = row.getValue(zipcode)  
  # Concatenating field values together ( str(part4) is in case zipcode is a numeric field instead of string)  
  row.setValue(field1, part1 + " " + part2 + " " + part3 + " " + str(part4))  
  cursor.updateRow(row)    
  row = cursor.next()
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

You are mixing the syntax of the two different types of cursors.  Review the documentation for the ArcPy Data Access cursors, paying particular attention to the examples.

0 Kudos
IanMurray
Frequent Contributor

ah you are now mixing and matching with the old and new cursors, I wrote that last bit for using the old style cursor(arcpy.UpdateCursor).

I'm not sure how to set it up with a while loop with the new cursors, the old style cursors had a good example with the while that I could use, the new style one does not.

0 Kudos
fumaniwada1
New Contributor

ahh I see what you are saying! I decided to use the old style cursor like you suggested using the "da"

and I got this error:

Traceback (most recent call last):

  File "C:/Users/ahutche1/Desktop/lol.py", line 34, in <module>

    part1 = row.getValue(address)

AttributeError: 'list' object has no attribute 'getValue'

#I will create a cursor to update the FullAddR field
with arcpy.da.UpdateCursor(env+hospitals+'.shp',[field1,address,city,state,zipcode]) as cursor: 
#I will use a while loop in order to copy all the information from the
 #city,state,address,and zipcode fields into the single FullAddR field.
    row = cursor.next() 
    while row:
#I am setting the variables for the fields I want to take information from
#in order to merge it into the new field I just created.
      part1 = row.getValue(address)  
      part2 = row.getValue(city)  
      part3 = row.getValue(state)  
      part4 = row.getValue(zipcode)  
      # Concatenating field values together ( str(part4) is in case zipcode is a numeric field instead of string)  
      row.setValue(field1, part1 + " " + part2 + " " + part3 + " " + str(part4))  
      cursor.updateRow(row)    
      
0 Kudos
IanMurray
Frequent Contributor

you are still using the new cursor, you will need to use the old cursor with the syntax you used before to work with the while loop I wrote.

  • cursor1 = arcpy.UpdateCursor(env+hospitals+'.shp') #I swill set up the update cursor 
  • row = cursor1.next() 
  • #I will use a while loop in order to copy all the information from the 
  • #city,state,address,and zipcode fields into the single FullAddR field. 
  • while row: 
  • #I am setting the variables for the fields I want to take information from 
  • #in order to merge it into the new field I just created. 
  •       part1 = row.getValue(address)   
  •       part2 = row.getValue(city)   
  •       part3 = row.getValue(state)   
  •       part4 = row.getValue(zipcode)   
  •       # Concatenating field values together ( str(part4) is in case zipcode is a numeric field instead of string)   
  •       row.setValue(field1, part1 + " " + part2 + " " + part3 + " " + str(part4))   
  •       cursor.updateRow(row)     
  •