2

Can anyone please explain the below implementation:

item = dict((i.tag, (type(i.text) == str and i.text.strip() or i.text)) for i in r if i.tag != "tid_item")

The values I am getting in various variables:

r is something like : <Element 'Rows' at 0x0000000003DA4540>
i.tag : resultNum
i : <Element 'resultNum' at 0x0000000003EA45A0>
i.text : 1

I am python novice and I am unable to understand how forloop is used within dictionary as values are also absurd.

Thanks for help!

Always_a_learner
  • 4,585
  • 13
  • 63
  • 112
  • check out list Comprehensions for python. a usefull link is http://www.secnetix.de/olli/Python/list_comprehensions.hawk – Nikos Vita Topiko Apr 10 '17 at 14:42
  • @NikosVitaTopiko Bit misleading as there's no list comprehension here. – miradulo Apr 10 '17 at 14:43
  • Same principle, though, see [PEP 289 - Generator Expressions](https://www.python.org/dev/peps/pep-0289/). I voted to close as too broad, though this could also be marked as a duplicate of [What does "list comprehension" mean and how do I use it](http://stackoverflow.com/questions/34835951/what-does-list-comprehension-mean-how-does-it-work-and-how-can-i-use-it) or some generator expression equivalent. – miradulo Apr 10 '17 at 14:49

2 Answers2

4

let's make first the code clearer:

dict(               #  constructor
    (i.tag,         #  key
         (type(i.text) == str and i.text.strip() or i.text)     # value
    ) 
    for i in r                  # driver of the generator
    if i.tag != "tid_item"      # conditional selector
)

What you have here, is not yet a dictionary, but a constructor of a dictionary, using a generator. After this is run, the variable item it is assigned to will contain a dictionary

the for loop inside this constructor is the generator to create all the elements: it loops over all elements in r, if it satisfies the condition, then it will create a tuple ( key, value) -> creating a 'on-the-fly' list of elements.

The boolean selector for the 'value' is also simple if we write it differently:

value = i.text.strip() if (type(i.text) == str) else i.text
1

Firstly, lets decompose your example:

item_init = ((i.tag, (type(i.text) == str and i.text.strip() or i.text)) for i in r if i.tag != "tid_item")
item = dict(item_init)

Now, if you look at the definition of the type dict in python (help(dict)), you will see that a dict object can be initialized with an iterable of (key, value) pairs. The item_init variable contains a generator and yield an iterable of tuples.

Next, look at the expression (i.tag, (type(i.text) == str and i.text.strip() or i.text)). You may not understand the second part of the expression because it looks like a boolean operation but is actually a conditionnal assignment operation which means:

if type(i.text) is str then assign i.text.strip() else, assign i.text

Finally, the item_init object is a generator of 2-uples where, for each element of r, the first part is the tag and the second is the text (stripped, if necessary). The tag will be used as keys and the text as values in the final dict object.

LucG
  • 1,238
  • 13
  • 25