Skip to main content

I am having issues setting an attribute within a python caller. 

I am reading in a list of strings, mutating the components in the list, then trying to overwrite the same list. Currently, the results of the output are the same as the input.

Below is an example of how I am doing it.

x = feature.getAttribute(list{}.item)
for i in len(x):
     <mutate items in list>
feature.setAttribute("list{}.item", x)

Can anyone let me know why this is not working, and how I can fix this? Thank you.

def processFeature(feature):
    x = feature.getAttribute('_list{}.item')
 
    for i in range(0,len(x)):
        _i = str(i)
        val = feature.getAttribute('_list{'+_i+'}.item')
        y = str(val)+'__'
        feature.setAttribute('_list{'+_i+'}.item',y)

 

The above will append '__' to the end of each item in the list.

 

A couple of things to note with your code, len(x) returns an int, ints aren't iterable, by placing it in range() we get a list which can be iterated over 

 

You need to indiviually update each item in the list using setAttribute()


def processFeature(feature):
    x = feature.getAttribute('_list{}.item')
 
    for i in range(0,len(x)):
        _i = str(i)
        val = feature.getAttribute('_list{'+_i+'}.item')
        y = str(val)+'__'
        feature.setAttribute('_list{'+_i+'}.item',y)

 

The above will append '__' to the end of each item in the list.

 

A couple of things to note with your code, len(x) returns an int, ints aren't iterable, by placing it in range() we get a list which can be iterated over 

 

You need to indiviually update each item in the list using setAttribute()

Sorry, the len(x) was an oversight in my example writing. 

Does this work if the output list is shorter than the current list? For example if I am using x.pop(_i) for some values, the items at the end of the list may be missed.


You can use this syntax to set the list, you don't necessarily need to iterate

feature.setAttribute("list{}.item", x)

But are you actually changing x in your code, before you use it to set the list attribute, e.g.

def processFeature(feature):
    x = feature.getAttribute('list{}.startIndex')
    x = istr(i)+"_test" for i in x]
    feature.setAttribute('list{}.startIndex', x)

 

 

 

 

 


Sorry, the len(x) was an oversight in my example writing. 

Does this work if the output list is shorter than the current list? For example if I am using x.pop(_i) for some values, the items at the end of the list may be missed.

in that case you could do something like this (exclude when list val = 2).

if your input is ("1","2","3","4","5"], your output will be  "1__","3__","4__","5__"]

import fme
import fmeobjects    
 
def processFeature(feature):
    x = feature.getAttribute('_list{}.item')
    new = e]
    
    for i in range(0,len(x)):
        _i = str(i)
        val = feature.getAttribute('_list{'+_i+'}.item')
        if val == 2:
            pass
        else:
            y = str(val)+'__'
            new.append(y)
 
    feature.setAttribute('_newList{}.item',new)

 


You can use this syntax to set the list, you don't necessarily need to iterate

feature.setAttribute("list{}.item", x)

But are you actually changing x in your code, before you use it to set the list attribute, e.g.

def processFeature(feature):
    x = feature.getAttribute('list{}.startIndex')
    x = istr(i)+"_test" for i in x]
    feature.setAttribute('list{}.startIndex', x)

 

 

 

 

 

Yea, you can also iterate over the list natively, in this case it is better to do your (@ebygomm​ ) approach (went the range()/len() approach as @lukehicks​ initial code include the len() of the input list)


For what it's worth, I prefer to use the enumerate function when iteration with for statement is required.

Example: Assign value of "_list{N}.item" to new attribute "_item_N"

        items = feature.getAttribute('_list{}.item')
        for i, v in enumerate(items):
            feature.setAttribute('_item_%d' % i, v)

 


Reply