2013-09-29

Condense Python Script with List Manipulations

=====
2013-12-23: FME 2014 supports <null>; a list attribute can also contain <null> elements. But FMEFeature.getAttribute and setAttribute methods do not treat <null> elements as <null>.
We should be aware this point in FME 2014+.
See more information here > Null in FME 2014: Handling Null with Python / Tcl
=====

Python API - fmeobjects.FMEFeature.getAttribute, setAttribute and removeAttribute functions treat list attributes (except nested lists) in the same manner as non-list attributes, as long as list elements are string instances. And also Python language has convenient and powerful mechanisms to manipulate list structures.
Therefore, a script with list manipulations could be condensed using those mechanisms effectively.

> Sharing: "Extracting a schema subset for dynamic schemas"
The script I've posted to the thread above, for example, can be replaced with this.
-----
# Example for "Extracting a schema subset for dynamic schemas"
# Last update: 2013-09-30
import fmeobjects

ListNames = ['attribute{}.' + s for s in ['name', 'native_data_type', 'fme_data_type']]

def keep_defs(feature):
    attr = map(feature.getAttribute, ListNames)
    keeps = [s.strip() for s in str(feature.getAttribute('_to_keep')).split(',')]
    if attr[0]:
        # t will be a tuple consisting of name, native_data_type and fme_data_type,
        # "name" matches with one of "keeps".
        newAttr = map(list, zip(*[t for t in zip(*attr) if t[0] in keeps]))
        map(feature.removeAttribute, ListNames)
        map(feature.setAttribute, ListNames, newAttr)
-----

This script is also possible, but probably is over-condensed one...
-----
import fmeobjects

ListNames = ['attribute{}.' + s for s in ['name', 'native_data_type', 'fme_data_type']]

def keep_defs(feature):
    attr = map(feature.getAttribute, ListNames)
    keeps = [s.strip() for s in str(feature.getAttribute('_to_keep')).split(',')]
    if attr[0]:
        map(lambda n, v: (feature.removeAttribute(n), feature.setAttribute(n, v)),
            ListNames, map(list, zip(*[t for t in zip(*attr) if t[0] in keeps])))
-----

=====
2014-01-26: More than enough is too much. Concise script is not always good.
See also "Efficiency of List Attribute Manipulation with Python".
=====

References:
List Comprehensions
Built -in "map" Function"zip" Function
Unpacking Argument Lists
Lambda Expressions

No comments:

Post a Comment