Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle 1 to n elements

I'm using xmltodict to parse an XML config. The XML has structures where an element can occur in 1 to n instances, where both are valid:

<items>
    <item-ref>abc</item-ref>
</items>

and

<items>
    <item-ref>abc</item-ref>
    <item-ref>dca</item-ref>
    <item-ref>abb</item-ref>
</items>

I'm parsing this with xmltodict as follows:

document['items']['item-ref']

and it gives back a single unicode or a list (depending the items found), so I always need to add an extra check to ensure if I need to handle a list or a string:

if isinstance(document['items']['item-ref'], list):
    my_var = document['items']['item-ref']
else:
    my_var = [document['items']['item-ref']] #create list manually

Is there a better/simpler/more elegant way to handle these?

like image 219
balas Avatar asked Dec 15 '14 15:12

balas


1 Answers

I am not sure of a super elegant way to do this. Python doesn't have any built-in methods or functions that will help you do this in a single line of code. Nevertheless, in the interest of consolidating code, you will want to do something. As matsjoyce mentioned in a comment, you may simply want to create a function that will take care of this logic for you.

def listn(val=None):
    if val is None:
        return []
    return val if isinstance(val, list) else [val]

>>> listn([1, 2, 3])
[1, 2, 3]
>>> listn()
[]
>>> listn(3)
[3]

Now you can simply call that function with your val and expect a list to be returned, whether it is a list, an int, or a NoneType object:

my_var = listn(document['items']['item-ref'])

(My first answer created a subclass of list, but that takes 6 lines instead of 4 and changes the type--not the most ideal side-effect.)

like image 117
Justin O Barber Avatar answered Oct 20 '22 12:10

Justin O Barber