u"""Converts an lxml.etree object to Python dict.

    >>> etree_to_dict(etree.Element('root'))
    {'root': None}

    :param etree.Element t: lxml tree to convert
    :returns d: a dict representing the lxml tree ``t``
    :rtype: dict

def etree_to_dict(t, trim=True, **kw):
    u"""Converts an lxml.etree object to Python dict.

    >>> etree_to_dict(etree.Element('root'))
    {'root': None}

    :param etree.Element t: lxml tree to convert
    :returns d: a dict representing the lxml tree ``t``
    :rtype: dict
    """
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    etree_to_dict_w_args = partial(etree_to_dict, trim=trim, **kw)

    if children:
        dd = defaultdict(list)
        d = {t.tag: {}}

        for dc in map(etree_to_dict_w_args, children):
            for k, v in dc.iteritems():
                # do not add Comment instance to the key
                if k is not etree.Comment:
                    dd[k].append(v)

        d[t.tag] = {k: v[0] if len(v) == 1 else v for k, v in dd.iteritems()}

    if t.attrib:
        d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems())
    if trim and t.text:
        t.text = t.text.strip()
    if t.text:
        if t.tag is etree.Comment and not kw.get('without_comments'):
            # adds a comments node
            d['#comments'] = t.text
        elif children or t.attrib:
            d[t.tag]['#text'] = t.text
        else:
            d[t.tag] = t.text
    return d