Reputation: 57701
I'm getting a ParseResult
which is a list of strings which represent numbers, for example,
['160', '240', '320', '480', '640']
which I'd like to convert to the corresponding list of integers:
[160, 240, 320, 480, 640]
However, I'm having trouble figuring out the right function to put into the setParseAction
method to achieve this result. Here is what I've tried so far (in Python 2):
In [1]: from pyparsing import *
In [2]: string = "densities: '160' '240' '320' '480' '640'"
In [3]: densities = LineStart() + "densities:" + OneOrMore(QuotedString(quoteChar="'"))("densities").setParseAction(lambda tokens: map(int, tokens))
In [4]: tokens = densities.parseString(string)
In [5]: tokens.asDict()
Out[5]: {'densities': [160]}
The parse action seems to only convert the first string to an integer. How can I modify this to achieve the desired list of integers? Or perhaps more generally: what do the tokens
given to the function in setParseAction
represent exactly?
Update
Following, Paul McGuire's comments and answer, I've tried using .setParseAction(tokenMap(int))
, but the resulting named result densities
is still only [160]
:
In [1]: from pyparsing import *
In [2]: string = "densities: '160' '240' '320' '480' '640'"
In [3]: densities = LineStart() + "densities:" + OneOrMore(QuotedString(quoteCha
...: r="'"))("densities").setParseAction(tokenMap(int))
In [4]: tokens = densities.parseString(string)
In [5]: tokens.asDict()
Out[5]: {'densities': [160]}
I've also tried gaining more insight into the process using traceParseAction
:
In [6]: densities = LineStart() + "densities:" + OneOrMore(QuotedString(quoteChar="'"))("densities").setParseAction(traceParseAction(tokenMap(int)))
In [7]: tokens = densities.parseString(string)
>>entering int(line: 'densities: '160' '240' '320' '480' '640'', 11, (['160', '240', '320', '480', '640'], {'densities': [(['160', '240', '320', '480', '640'], {})]}))
<<leaving int (ret: [160, 240, 320, 480, 640])
The ret
shown here is the desired result, but somehow it doesn't appear to be the same as tokens.asDict()['densities']
?
Upvotes: 4
Views: 977
Reputation: 63762
I think the pyparsing_common.convertToInteger
parse action will do the trick, which is implemented using pyparsing.tokenMap(int)
.
pyparsing.tokenMap
will generate parse actions that take a function that will operate on a single token, and apply it to all the parsed tokens. More info on tokenMap
here: https://pythonhosted.org/pyparsing/pyparsing-module.html#tokenMap
EDIT:
Seems that Group
ing is also required to get this to work:
densities = (LineStart()
+ "densities:"
+ Group(OneOrMore(QuotedString(quoteChar="'")).setParseAction(tokenMap(int)))("densities")
)
Or, move the parse action inside the OneOrMore
:
densities = (LineStart()
+ "densities:"
+ OneOrMore(QuotedString(quoteChar="'").setParseAction(tokenMap(int)))("densities")
)
Upvotes: 3