3

I'm trying to replicate output to a text file from an attribute table using the write() method to transfer the values to the .txt file. The program writes the values but groups each row of values into braces [] and returns a u"value" format for each value. Additionally blanks are represented by the "None". Finally, the order of the field values are wrong even though I tried to build an order using a criteria list to refine the arcpy.ListFields()

This is the output I'm now getting:

[100.0, u'', 304604, 1298977.349872, 295805.476068, u'113984001', u'113984001', None, None, 4, u'D472B444-7F3C-40E9-85B1-A6A700EBFBEE', u'', 2030, u'BT-501'][100.0, u'', 32204, 1343091.764101, 194014.427182, u'134531001', u'134531001', None, None, 4, u'D18279D5-34D7-46A7-9342-A6AB00A55F48', u'', 3660, u'IS-501']

I would like to get this:

D472B444-7F3C-40E9-85B1-A6A700EBFBEE,113984001,113984001,1298977.349872,295805.476068,304604,,100,BT-501,2030,4,,, D18279D5-34D7-46A7-9342-A6AB00A55F48,134531001,134531001,1343091.764101,194014.427182,32204,,100,IS-501,3660,4,,, 1ACC967C-241F-4C07-BB7A-A6AC00B632E3,9666001,9666001,1275486.924555,280097.24814,259088,,100,SH-501B,,2,,,A

Here's my code:

inFields = ["UniqueID","Address_ID","Account_ID","X","Y","Ref_ID","Side","Score","Route","Sequence","Service_Day","Demand_2","Demand_3","Week"]

    outputWS = r"C:\RS_Data\Workspace\BATCH_CO_161_imports\gisdb\layers.gdb"

        finalFC = os.path.basename(layer)
        print finalFC
        day = time.strftime("%m%d%Y")
        arcpy.FeatureClassToFeatureClass_conversion(layer, outputWS, finalFC)
        outPath = 'S:\\Shared\\RouteSmart\\CO_161_Cleanscapes\\To_Tower'
        name = os.path.basename(finalFC)
        dataFields = arcpy.ListFields(finalFC)
        file = os.path.join(outPath, ("{0}{1}{2}".format(day,name,".txt")))
        print file
        f = open(file, "w")
        writeFields = []
        for field in dataFields:
            if field.name in inFields:
                writeFields.append(field)
        for row in arcpy.SearchCursor(finalFC):
            fieldVals = [row.getValue(field.name) for field in writeFields]
            f.writelines(str(fieldVals))
        del row
        f.close()

Is there a way I can specify the order in which the values are written, remove the u"value" formatting as well as the []'s around each row, replace "None" with "" and have it write each row as a new line in the text file?

After taking a mix tips from the answers I've gotten it close. The None's are still there but that's the only thing left to resolve. Here's the modified code:

        arcpy.FeatureClassToFeatureClass_conversion(layer, outputWS, finalFC)[0]
        outPath = 'S:\\Shared\\RouteSmart\\CO_161_Cleanscapes\\To_Tower'
        name = os.path.basename(finalFC)

        dataFields = [i.name for i in arcpy.ListFields(finalFC)]

        file = os.path.join(outPath, ("{0}{1}{2}".format(day,name,".txt")))
        print file
        f = open(file, "w")

        writeFields = []

        for field in inFields:
            if field in dataFields:
                writeFields.append(field)

        for row in arcpy.SearchCursor(finalFC):
            # No longer need to reference name property (field.name)
            fieldVals = [row.getValue(field) for field in writeFields]
            # Replace nulls with empty strings
            fieldsVals = ['' if i is None else i for i in fieldVals]
            # Create a comma-separated string of values
            fieldVals = [str(field) for field in fieldVals]
            out_string = ','.join(fieldVals)
            # Write the string--not the list--to the table
            f.writelines(out_string)
        del row
        f.close()

    arcpy.Delete_management(layer)
    arcpy.Delete_management("OldSeq")
  • If you change for field in datafields to for field in infields and fix the following part accordingly, you will get your data in the right order. Removal of u'' and brackets is another issue not related to gis but using right python module to get and write values. I recommend you to look into **lovely ** csv built-in module and DictionaryWriter of this module. – fatih_dur Nov 3 '16 at 22:00
  • What version of ArcGIS are you using? Please edit your question to include it in the tags. – Tom Nov 3 '16 at 22:00
  • Thanks for the tip. I'm using 10.2.2. I've edited it in the tags. – geoJshaun Nov 3 '16 at 23:22
2

Though there are easier ways to achieve your goal, here's a minimal-modification fix for your script. See the included comments:

inFields = ["UniqueID","Address_ID","Account_ID","X","Y","Ref_ID","Side","Score","Route","Sequence","Service_Day","Demand_2","Demand_3","Week"]

outputWS = r"C:\RS_Data\Workspace\BATCH_CO_161_imports\gisdb\layers.gdb"

finalFC = os.path.basename(layer)
print finalFC
day = time.strftime("%m%d%Y")

arcpy.FeatureClassToFeatureClass_conversion(layer, outputWS, finalFC)
outPath = 'S:\\Shared\\RouteSmart\\CO_161_Cleanscapes\\To_Tower'
name = os.path.basename(finalFC)

# Changed to a list comprehension to grab the field names directly
dataFields = [i.name for i in arcpy.ListFields(finalFC)]

file = os.path.join(outPath, ("{0}{1}{2}".format(day,name,".txt")))
print file
f = open(file, "w")

writeFields = []

for field in inFields:
    if field in dataFields:
        writeFields.append(field)

for row in arcpy.SearchCursor(finalFC):
    # No longer need to reference name property (field.name)
    fieldVals = [row.getValue(field) for field in writeFields]
    # Replace nulls with empty strings
    fieldVals = ['' if i is None else i for i in fieldVals]
    # Create a comma-separated string of values
    out_string = ','.join(fieldVals)
    # Write the string--not the list--to the table
    f.writelines(out_string)
del row
f.close()

More info on:

The join method on strings

List comprehensions

  • Thank you for the modification. I'm now getting an attribute error "AttributeError: 'unicode' object has no attribute 'name'" even though the list was converted using arcpy.ListFields – geoJshaun Nov 3 '16 at 23:20
  • Try chaning arcpy.FeatureClassToFeatureClass_conversion(layer, outputWS, finalFC) to finalFC=arcpy.FeatureClassToFeatureClass_conversion(layer, outputWS, finalFC)[0] – fatih_dur Nov 4 '16 at 1:42
  • @ShaunO, see the edit. I had forgotten to remove the "field.name" within the cursor. – Tom Nov 4 '16 at 15:13
  • @Tom Got it. It's working pretty good now but the None's are still there. I added fieldVals as the paramter to .join() and changed the parameter for writelines to (out_string + "\n") so the txt file would have new line for each row of values. I looked into other ways of getting rid of None and they are consistent with the code you provided. Thank you. – geoJshaun Nov 4 '16 at 22:00
  • 1
    @Tom FieldVals was written as FieldsVals in the section to replace None with ' '. Works perfectly now. – geoJshaun Nov 7 '16 at 18:24
2

Your are supply str() a list which python will optimistically convert to a string. That is really intended for you as a programmer to undertand what the string contains.

Instead you need to convert the list to a string yourself and add a delimiter explicitly:

f.writelines(   ",".join(fieldvals) )

Join will expect fieldvals to only consist of strings, so you need to convert each field individualy first:

fieldvals = [str(field) for field in fieldvals]

You can reorder the fields by defining writeFields explicitly:

writeFields = ['first Field', 'second Field']
  • This was a huge help and I borrowed from your suggestion in getting to the final answer but I could only check one answer. Thank you. – geoJshaun Nov 4 '16 at 22:01

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.