Skip to main content
Question

Python setAttribute list of dict attributes

  • February 15, 2018
  • 6 replies
  • 192 views

Forum|alt.badge.img

Hello All,

There are a lot of questions around this topic (ie., https://knowledge.safe.com/questions/51878/how-to-setattribute-lists-in-pythoncaller.html), but somehow I'm not able to make it work. Here is the background:

I have an xml that I'm reading it and getting some attributes to pass them in FME for further processing. I have created a list of dict in order to group them, below is the code I'm using:

 

domain.append({'chartnumb_value':chartnumb_value,
'nm_numbers': get_chart_nm_numbers(update),
'region': get_region(update)})
print domain
Here is the print of the above::

[{'nm_numbers': u'3040(P)/17', 'region': u'UNITED ARAB EMIRATES', 'chartnumb_value': u'Chart No: 8101'}]

[{'nm_numbers': u'3027(P)/17', 'region': u'BANGLADESH', 'chartnumb_value': u'Chart No: 8166'}]

[{'nm_numbers': u'3038(P)/17', 'region': u'AUSTRALIA', 'chartnumb_value': u'Chart No: AUS778'}]

I want to get the 'chartnumb_value', 'nm_numbers', and 'region' into separate columns. For this I'm using after the .append the following:

num_items = len(domain)
for i in range(num_items):
chartnumb_value = domain[i]["chartnumb_value"]
feature.setAttribute("_list{{{}}}".format(i), chartnumb_value

When I run the above code, I'm always getting one value, no matter if I append {} after the list in the attributes to expose (_list{}.chartnumb_value)

I've been going in a "loop" to find the solution, but is not working for me any solutions out there, probably (which is obvious) I'm missing something.

 

 

Thanks in advance for all your help on this

 

Cesar

This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

6 replies

daveatsafe
Safer
Forum|alt.badge.img+20
  • Safer
  • February 15, 2018

Hi @csuarez,

Please try:

num_items = len(domain)
for i in range(num_items):
    entry = domain[i]
    for key in entry:
        feature.setAttribute("_list{{{}}}".format(i) + '.' + key, entry[key])

This will create the following attributes on the feature:

'_list{0}.chartnumb_value' has value `Chart No: 8101'
'_list{0}.nm_numbers' has value `3040(P)/17'
'_list{0}.region' has value `UNITED ARAB EMIRATES'
`_list{1}.chartnumb_value' has value `Chart No: 8166'
`_list{1}.nm_numbers' has value `3027(P)/17'
`_list{1}.region' has value `BANGLADESH'
`_list{2}.chartnumb_value' has value `Chart No: AUS778'
`_list{2}.nm_numbers' has value `3038(P)/17'
`_list{2}.region' has value `AUSTRALIA'


Forum|alt.badge.img
  • Author
  • February 15, 2018

Hi @csuarez,

Please try:

num_items = len(domain)
for i in range(num_items):
    entry = domain[i]
    for key in entry:
        feature.setAttribute("_list{{{}}}".format(i) + '.' + key, entry[key])

This will create the following attributes on the feature:

'_list{0}.chartnumb_value' has value `Chart No: 8101'
'_list{0}.nm_numbers' has value `3040(P)/17'
'_list{0}.region' has value `UNITED ARAB EMIRATES'
`_list{1}.chartnumb_value' has value `Chart No: 8166'
`_list{1}.nm_numbers' has value `3027(P)/17'
`_list{1}.region' has value `BANGLADESH'
`_list{2}.chartnumb_value' has value `Chart No: AUS778'
`_list{2}.nm_numbers' has value `3038(P)/17'
`_list{2}.region' has value `AUSTRALIA'

Hi @DaveAtSafe,

 

I think my problem is related to the actual length of the list of dict. when I print "num_items", I'm always getting 1

 

 

1
{'nm_numbers': u'3040(P)/17', 'region': u'UNITED ARAB EMIRATES', 'chartnumb_value': u'Chart No: 8101'}
1
{'nm_numbers': u'3027(P)/17', 'region': u'BANGLADESH', 'chartnumb_value': u'Chart No: 8166'}
1
{'nm_numbers': u'3038(P)/17', 'region': u'AUSTRALIA', 'chartnumb_value': u'Chart No: AUS778'} 

 

the reason (for me) that is failing is that I'm doing the data processing one at a time, then creating my dict by appending them. I've tried also with the enumerate() option suggested on another response from @takashi, but still I'm always getting either 1 or 0 (using enumerate).

 

 

Any tips on this?

 

Thank you very much for your quickly response 

 

C

daveatsafe
Safer
Forum|alt.badge.img+20
  • Safer
  • February 15, 2018
Hi @DaveAtSafe,

 

I think my problem is related to the actual length of the list of dict. when I print "num_items", I'm always getting 1

 

 

1
{'nm_numbers': u'3040(P)/17', 'region': u'UNITED ARAB EMIRATES', 'chartnumb_value': u'Chart No: 8101'}
1
{'nm_numbers': u'3027(P)/17', 'region': u'BANGLADESH', 'chartnumb_value': u'Chart No: 8166'}
1
{'nm_numbers': u'3038(P)/17', 'region': u'AUSTRALIA', 'chartnumb_value': u'Chart No: AUS778'} 

 

the reason (for me) that is failing is that I'm doing the data processing one at a time, then creating my dict by appending them. I've tried also with the enumerate() option suggested on another response from @takashi, but still I'm always getting either 1 or 0 (using enumerate).

 

 

Any tips on this?

 

Thank you very much for your quickly response 

 

C
Hi @csuarez,

 

If you are populating the domain list from the input features, you may need to use a Python Class to process your data instead of a function. The class allows you to read multiple features to build up your dictionary in the input method, then output the feature with the list in the close method.

 

It would help if you could give me a higher level view of what you are trying to accomplish with the Python.

 


takashi
Celebrity
  • February 15, 2018
Hi @DaveAtSafe,

 

I think my problem is related to the actual length of the list of dict. when I print "num_items", I'm always getting 1

 

 

1
{'nm_numbers': u'3040(P)/17', 'region': u'UNITED ARAB EMIRATES', 'chartnumb_value': u'Chart No: 8101'}
1
{'nm_numbers': u'3027(P)/17', 'region': u'BANGLADESH', 'chartnumb_value': u'Chart No: 8166'}
1
{'nm_numbers': u'3038(P)/17', 'region': u'AUSTRALIA', 'chartnumb_value': u'Chart No: AUS778'} 

 

the reason (for me) that is failing is that I'm doing the data processing one at a time, then creating my dict by appending them. I've tried also with the enumerate() option suggested on another response from @takashi, but still I'm always getting either 1 or 0 (using enumerate).

 

 

Any tips on this?

 

Thank you very much for your quickly response 

 

C
Agreed. And I think  it would not be essential to create the 'domain' list containing dictionaries.

 

class FeatureProcessor(object):
    def __init__(self):
        self.features = []
        
    def input(self, feature):
        self.features.append(feature)
        
    def close(self):
        newFeature = self.features[0]
        for i, feature in enumerate(self.features):
            #
            # TODO: Get or calculate these values.
            # chartnumb_value = ?
            # update = ?
            # num_numbers = get_chart_nm_numbers(update)
            # region = get_region(update)
            #
            newFeature.setAttribute('_list{%d}.chartnumb_value' % i, chartnumb_value)
            newFeature.setAttribute('_list{%d}.num_numbers' % i, num_numbers)
            newFeature.setAttribute('_list{%d}.region' % i, region)
        self.pyoutput(newFeature)

 


Forum|alt.badge.img
  • Author
  • February 16, 2018

Hi @DaveAtSafe, @takashi,

 

My apologies for the silence on responding, I'm addressing your comments. Truth is I'm "almost" new in python, but very new in FME Python.

 

My script reads an xml (which is btw painful), then extract a specific tag (index value) and then starts to process it based on the index value. This is where I think the problem is. I'm trying to adjust my code to @takashi's suggestion, obviously challenging for me.

Once again, thank you

C


Forum|alt.badge.img
  • Author
  • March 27, 2018

My apologies, truly for not posting the answer here before, after sending the python code and source to safe (thanks @DaveAtSafe), the new approach is cleaner and easy to use. I'm attaching the code for future references while dealing with this somehow scenarios.

Thanks

Cesar

readxml-safe.fmw