Parse weak ciphers out of an nmap.xml report
I don't believe that this does what you want, for a few reasons.

First, I'm not 100% on interleaving ElementTree iterators, but this may pick up more elements than you want; for example, what happens when the document is something like

&lt;host&gt;
&lt;address addr="1.1.1.1"/&gt;
&lt;/host&gt;
&lt;host&gt;
&lt;address addr="2.2.2.2"/&gt;
&lt;elem key="md5"/&gt;
&lt;/host&gt;


It's at least plausible to me that both IP addresses would show up in the md5 list. Even if it doesn't, you should strive to use code that has clear semantics.

Second, your filters check that ip not in md5Stack but what you add to md5Stack is ip.split(',').



Let's try this:

from xml.etree import ElementTree

def extract_weak_ips(nmap_root):
    md5_ips = set()
    sha1_ips = set()
    hosts = list(nmap_root.iter('host'))
    for host in hosts:
        addresses = [address.get('addr').split(',') 
                     for address in host.findall(".//address[@addr]")]
        if host.find(".//elem[@key='md5']") is not None:
            md5_ips.update(addresses)
        if host.find(".//elem[@key='sha1']") is not None:
            sha1_ips.update(addresses)

def print_ip_set(s, key):
    for ip in s:
        print ' %s :: %s' % (ip, key)

if __name__ == '__main__':
    parser = ElementTree.XMLParser()
    parser.parser.UseForeignDTD(True)
    md5_ips, sha1_ips = extract_weak_ips(ElementTree.parse('nmap.xml', parser).getroot())
    print_ip_set(md5_ips, 'md5')
    print_ip_set(sha1_ips, 'sha1')


I've extracted code into clear functions, and I'm using XPath queries so that the XML engine is doing the work of querying XML, not your application-specific code.



I think that in this case the list-comprehension approach is less readable than the code with for-loops, but if you really want list comprehensions, try this:

def extract_ips_with_key_type(nmap_root, key_type):
    query = ".//elem[@key='%s']" % key_type
    return set(apply(
        itertools.chain,
        (address.get('addr').split(',')
         for host in nmap_root.iter('host')
         if host.find(query) is not None
         for address in host.findall('.//address[@addr]')))