0

I am following the tutorial here for how to convert a csv to shp using pyshp. I am almost there, with one issue. In the tutorial, the person loops over the rows in the csv, and for each field, assigns the value of that field to a variable (shortened example):

import shapefile # import pyshp library
trees_shp = shapefile.Writer(shapefile.POINT)
for row in reader:
   tree_id = row[0]
   address = row[1]
   town = row[2]
   ....
   condition = row[11]
   latitude = row[12]
   longitude = row[13]

They then record the new point with attributes like this:

trees_shp.point(float(longitude),float(latitude))
trees_shp.record(tree_id, address, town, ..., condition)

My question is, is there another (better) way to record field values that are stored in a list (or comma separated string)? i.e. I am looking to record the attributes that are stored in 2 variables (for each row/point):

row_str = 'fieldValue1, fieldValue2, fieldValue3'
row_list = ['fieldValue1', 'fieldValue2', 'fieldValue3']

I would like to just do something like:

outShpWriter = shapefile.Writer(shapefile.POINT)
outShpWriter.record(row_str) 
# or
outShpWriter.record(row_list) 

but each gives me the following error:

  File "/usr/local/lib/python2.7/dist-packages/shapefile.py", line 1071, in record
    record = [recordList[i] for i in range(fieldCount)]
IndexError: tuple index out of range

Is there a workaround besides having to explicitly define variables i.e. (f1 = row_list[0]) and record those variables to the shp?

I ask because the number of fields/fields themselves may change and I would like to automate as much as possible to make it flexible.

1

record method definition in shapefile module:

def record(self, *recordList, **recordDict):
    """Creates a dbf attribute record. You can submit either a sequence of
    field values or keyword arguments of field names and values. Before
    adding records you must add fields for the record values using the
    fields() method. If the record values exceed the number of fields the
    extra ones won't be added. In the case of using keyword arguments to specify
    field/value pairs only fields matching the already registered fields
    will be added."""

So you can use asteriks '*' for list, and split method and asteriks for string in record method like that:

# *row_list gives 'fieldValue1', 'fieldValue2', ... for a list
outShpWriter.record(*row_list) 

# *row_str.split(',') gives 'fieldValue1', 'fieldValue2', ... for a string
outShpWriter.record(*row_str.split(',')) 

But fieldValueX values must be in the same order as field names created for shapefile(.shp).

Or you should use dictionary as @gene states in comments by links.

You probably get the error when you use row_str, because a string is iterable object in Python and record() method iterates every characters in the string as if each character is a field value. So length of string is more than number of fields, and you get IndexError: tuple index out of range.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.