Hut8
Hut8

Reputation: 6342

Why are my Python arguments not unpacking?

I am a bit confused about unpacking argument lists. I am trying to make an XSL-FO file programatically and therefore need to insert a variable number of elements at some point in the file. Of course I could do this other ways (XML/XSLT, other XML methods, etc) but I'd like to know why this isn't working because maybe my basic knowledge of Python is a bit rusty. Right by "RIGHT HERE" I'm trying to insert my column_elms list as a variable number of parameters. Note that this does not take a list, and that if I copy what's on the next line (E("table-column...), over and over it does, in fact, produce the desired output (multiple table-column elements. But with unpacking this, it just gives me one table-column element no matter what. What's going on‽‽‽

from lxml.builder import ElementMaker
from lxml import etree as ET  
COLUMNS = 8
E = ElementMaker(namespace='http://www.w3.org/1999/XSL/Format',
                 nsmap={'fo':"http://www.w3.org/1999/XSL/Format"})
column_elms = [E("table-column",{"column-width":"41mm"})] * COLUMNS
root = E("root",
         E("layout-master-set",
           E("simple-page-master",
             {"master-name":"label-sheet",
                "margin-left":"5mm",
                "margin-right":"5mm",
                "margin-top":"14mm",
                "margin-bottom":"14mm"},
             E("region-body"))),
         E("page-sequence",
           {"master-reference":"label-sheet"},
             E("flow", {"flow-name":"xsl-region-body"},
                E("table", *column_elms # **RIGHT HERE**
                                        # E("table-column",{"column-width":"41mm"}),
                    ))))

Upvotes: 1

Views: 110

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1125018

You are creating a list with COLUMNS copies of the same object:

column_elms = [E("table-column",{"column-width":"41mm"})] * COLUMNS

The above code does not call E() 8 times, it call it once then puts 8 references in the list.

It's as if you ran:

column_elms = []
tcolumn = E("table-column",{"column-width":"41mm"})
for i in range(COLUMNS):
    column_elms.append(tcolumn)

Use a list comprehension instead:

column_elms = [E("table-column",{"column-width":"41mm"}) for _ in xrange(COLUMNS)]

which would evaluate the E(..) expression for each run through the loop.

Upvotes: 1

Related Questions