Skip to main content
Solved

How do I obtain list index information using PythonCaller?

  • August 3, 2021
  • 7 replies
  • 28 views

The problem:

I have two lists which are related to each other by way of index so lets say we have the following format -

 

List 1 (contains 4 Elements)

List 2 (contains 4 Elements)

 

The Elements in each list relate to one another so Element 0 in List 1 is directly relatable to Element 0 in List 2. Element 1 in List 1 is directly relatable to Element 1 in List 2 and so on and so forth for the rest of the Elements.

 

What I'd like to Achieve:

If any Element stored in List 1 = "foo" -- I would like to remove it as well as the related Element in List 2. I think this is easily achieved if it is possible to extract not just the attribute of the Element in the lists, but the Element Index as well. How do I do this?

 

I am able to extract the attribute name of each Element easily by using:

my_list = feature.getAttribute('my_list{})

 

Thanks in Advance.

 

Best answer by warrendev

Try this. Not sure if this is what you are looking for, but maybe this will help. 

 

Let's say I have 2 lists called list1 and list2.

list1 = ['foo', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

I want to iterate through the list and when I find a value in list1 that matches 'foo', I will remove that from list1 as well as the item at that specific index in list2.

my_list1 = feature.getAttribute('list1{}')
my_list2 = feature.getAttribute('list2{}')
        
for index, list1_value in enumerate(my_list1):
        if list1_value == 'foo':
                del my_list1[index]
                del my_list2[index]
feature.setAttribute('my_list1{}', my_list1)
feature.setAttribute('my_list2{}', my_list2)

 

Now 'foo' is removed from my_list1{} and the value is removed from my_list2{} at the same index.

new_list 

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.

7 replies

daraghatsafe
Forum|alt.badge.img
  • 135 replies
  • August 3, 2021

Hey @mrajmoss​ would you be able to share an example workspace?


warrendev
Enthusiast
Forum|alt.badge.img+26
  • Enthusiast
  • 121 replies
  • Best Answer
  • August 3, 2021

Try this. Not sure if this is what you are looking for, but maybe this will help. 

 

Let's say I have 2 lists called list1 and list2.

list1 = ['foo', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

I want to iterate through the list and when I find a value in list1 that matches 'foo', I will remove that from list1 as well as the item at that specific index in list2.

my_list1 = feature.getAttribute('list1{}')
my_list2 = feature.getAttribute('list2{}')
        
for index, list1_value in enumerate(my_list1):
        if list1_value == 'foo':
                del my_list1[index]
                del my_list2[index]
feature.setAttribute('my_list1{}', my_list1)
feature.setAttribute('my_list2{}', my_list2)

 

Now 'foo' is removed from my_list1{} and the value is removed from my_list2{} at the same index.

new_list 


  • Author
  • 3 replies
  • August 4, 2021

Try this. Not sure if this is what you are looking for, but maybe this will help. 

 

Let's say I have 2 lists called list1 and list2.

list1 = ['foo', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

I want to iterate through the list and when I find a value in list1 that matches 'foo', I will remove that from list1 as well as the item at that specific index in list2.

my_list1 = feature.getAttribute('list1{}')
my_list2 = feature.getAttribute('list2{}')
        
for index, list1_value in enumerate(my_list1):
        if list1_value == 'foo':
                del my_list1[index]
                del my_list2[index]
feature.setAttribute('my_list1{}', my_list1)
feature.setAttribute('my_list2{}', my_list2)

 

Now 'foo' is removed from my_list1{} and the value is removed from my_list2{} at the same index.

new_list 

This is exactly what I'm looking for, however using it does not give the same results that you seem to get.

 

For me this method produces the following results:

list1 = ['value2', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

Whereby anytime the value 'foo' is encountered it is replaced by the value it encounters next within the list. The list size is not reduced, but the values are changed.

 

Here is another example for clarification:

 

Starting data:

list1 = ['foo', 'value2', 'foo', 'value4']
list2 = ['value1', 'value2', 'value3', 'value4']

Output using your method above:

list1 = ['value2', 'value2', 'value4', 'value4']
list2 = ['value2', 'value2', 'value4', 'value4']

 


ebygomm
Influencer
Forum|alt.badge.img+44
  • Influencer
  • 3427 replies
  • August 4, 2021

To replace the value with the next in the list you can do something like this

def processFeature(feature):
    my_list1 = feature.getAttribute('list1{}')
    my_list2 = feature.getAttribute('list2{}')
        
    for index, list1_value in enumerate(my_list1):
        if list1_value == 'foo':
            feature.setAttribute('list1{'+str(index)+'}',my_list1[index+1])
            feature.setAttribute('list2{'+str(index)+'}',my_list1[index+1])

It's not clear from your example whether you want the list item in list 2 to be replaced with the list item from list 1 or the next list item in list 2 when foo is encountered. You would have to handle the exception if foo was ever encountered as the last item in the list

 


  • Author
  • 3 replies
  • August 4, 2021

To replace the value with the next in the list you can do something like this

def processFeature(feature):
    my_list1 = feature.getAttribute('list1{}')
    my_list2 = feature.getAttribute('list2{}')
        
    for index, list1_value in enumerate(my_list1):
        if list1_value == 'foo':
            feature.setAttribute('list1{'+str(index)+'}',my_list1[index+1])
            feature.setAttribute('list2{'+str(index)+'}',my_list1[index+1])

It's not clear from your example whether you want the list item in list 2 to be replaced with the list item from list 1 or the next list item in list 2 when foo is encountered. You would have to handle the exception if foo was ever encountered as the last item in the list

 

Hi thanks for commenting, I do not wish to replace anything in either list, I wish to remove any cases of "foo" that I find in List 1, then I wish to remove the index in List 2 that matches where "foo" was in List 1.

 

So if "foo" was found at index 3 in List 1, I would remove it and then also find index 3 in list 2 and remove that as well (As list 2 is related to list 1 via the indexes).

Does this help explain it better?


warrendev
Enthusiast
Forum|alt.badge.img+26
  • Enthusiast
  • 121 replies
  • August 4, 2021

This is exactly what I'm looking for, however using it does not give the same results that you seem to get.

 

For me this method produces the following results:

list1 = ['value2', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

Whereby anytime the value 'foo' is encountered it is replaced by the value it encounters next within the list. The list size is not reduced, but the values are changed.

 

Here is another example for clarification:

 

Starting data:

list1 = ['foo', 'value2', 'foo', 'value4']
list2 = ['value1', 'value2', 'value3', 'value4']

Output using your method above:

list1 = ['value2', 'value2', 'value4', 'value4']
list2 = ['value2', 'value2', 'value4', 'value4']

 

@mrajmoss​ I've attached an example workspace that hopefully will help.

example 


  • Author
  • 3 replies
  • August 5, 2021

This is exactly what I'm looking for, however using it does not give the same results that you seem to get.

 

For me this method produces the following results:

list1 = ['value2', 'value2', 'value3']
list2 = ['value1', 'value2', 'value3']

Whereby anytime the value 'foo' is encountered it is replaced by the value it encounters next within the list. The list size is not reduced, but the values are changed.

 

Here is another example for clarification:

 

Starting data:

list1 = ['foo', 'value2', 'foo', 'value4']
list2 = ['value1', 'value2', 'value3', 'value4']

Output using your method above:

list1 = ['value2', 'value2', 'value4', 'value4']
list2 = ['value2', 'value2', 'value4', 'value4']

 

Thanks a lot, this completely solved it for me. The part of the code I was missing was:

 

        # Remove the existing list attributes from the feature so we can reset them
        feature.removeAttribute('mylist1{}')
        feature.removeAttribute('mylist2{}')

So I wasn't clearing the values in FME before setting them again. Great work!