0

I want to get some data from XML and return it in the same variable, so i do like this before return:

for element in response:
    document = parseString(element)

    try:
        element = {
            'scopes':  document.getElementsByTagNameNS('*', 'Scopes')[0].firstChild.nodeValue,
            'address': document.getElementsByTagNameNS('*', 'XAddrs')[0].firstChild.nodeValue
        }
    except:
        element = False

return response

But the response still contains raw xml data instead of parsed results... Basically I want that element = ... value returned to response value.

Kin
  • 4,466
  • 13
  • 54
  • 106
  • 1
    What is the type of response? – aisbaa Apr 15 '14 at 12:37
  • @aisbaa is a simple array `[1,2,3,4,5]` – Kin Apr 15 '14 at 12:39
  • Related, though perhaps not a duplicate: [Python: How do I pass a variable by reference?](http://stackoverflow.com/q/986006/395760) –  Apr 15 '14 at 12:41
  • So...., I bet response isn't an array of integers. Are you saying that response is a list of strings and you want to replace each string with the elements dict built from the string? – tdelaney Apr 15 '14 at 17:35

3 Answers3

0

Edit: Improving the answer according delnan and jonrsharpe.

The problem with your code is that, when you loop

for element in response

in each iteration element will be pointing to a new created object couse the lines:

element = {
            'scopes':  document.getElementsByTagNameNS('*', 'Scopes')[0].firstChild.nodeValue,
            'address': document.getElementsByTagNameNS('*', 'XAddrs')[0].firstChild.nodeValue
        }

and the object it was pointing before still the same. You can try this.

for index,element in enumerate(response):
    document = parseString(element)

    try:
        response[index]= {
            'scopes':  document.getElementsByTagNameNS('*', 'Scopes')[0].firstChild.nodeValue,
            'address': document.getElementsByTagNameNS('*', 'XAddrs')[0].firstChild.nodeValue
        }
    except:
         response[index]= False

return response
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
  • 1
    Careful! What you (and many other Python people) call a reference has little to do with what computer scientists, C++ people, and PHP people call a reference. The semantics are very different. –  Apr 15 '14 at 12:39
  • Each, in PHP you can simple pass value like `foreach($response as &$element)` and do not need any indexes. – Kin Apr 15 '14 at 12:41
  • `element` will *not* be a copy. On each iteration, `element` will "point to" the *same object* that the current index of the list points to. `response[index] = ` then points that list index to *a new object*. – jonrsharpe Apr 15 '14 at 12:44
0

Assuming that response is a list of strings and you want to replace those strings with the parsed elements dict..., that's easy. Since lists are mutable containers, you can replace the elements as you go. No need to return the list... the one you pass in is changed.

def convert_response_to_elements(response):
    for index, element_str in enumerate(response):
        document = parseString(element_str)
        try:
            element = {
                'scopes':  document.getElementsByTagNameNS('*', 'Scopes')[0].firstChild.nodeValue,
                'address': document.getElementsByTagNameNS('*', 'XAddrs')[0].firstChild.nodeValue
        }
        except:
            element = False
        response[index] = element
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • I assume it's safe to edit `response` if you're iterating over it with `enumerate()`? – 2rs2ts Apr 15 '14 at 17:51
  • 1
    @2rs2ts In this case, yes. It works because its only changing elements that have already been iterated. You only get into trouble if you change what hasn't been iterated yet (e.g., deleting an item, meaning that you've changed the index). Simply substituting an already-iterated element doesn't mess up iteration of a list. – tdelaney Apr 15 '14 at 18:00
0

Since response is a list, I would use pythons list comprehension. This will create new list without modifying old one.

new_response = [modify_element(element) for element in response]

Later if you want to remove elements that equal to False you can use filter function:

without_false = filter(lambda element: bool(element), new_response)
BenMorel
  • 34,448
  • 50
  • 182
  • 322
aisbaa
  • 9,867
  • 6
  • 33
  • 48