操作Python词典以删除空值

时间:2014-09-15 15:58:03

标签: python dictionary

如果密钥包含'空'我试图删除键/值对。值。

我尝试过以下词典理解并尝试以长篇形式进行,但它似乎并没有真正做任何事情而且没有错误。

def get_Otherfiles():
    regs = ["(.*)((U|u)ser(.*))(\s=\s\W\w+\W)", "(.*)((U|u)ser(.*))(\s=\s\w+)", "(.*)((P|p)ass(.*))\s=\s(\W(.*)\W)", "(.*)((P|p)ass(.*))(\s=\s\W\w+\W)"]
    combined = "(" + ")|(".join(regs) + ")"
    cred_results = []
    creds = []
    un_matched = []
    filesfound = []
    d = {}
    for root, dirs, files in os.walk(dir):
        for filename in files:
            if filename.endswith(('.bat', '.vbs', '.ps', '.txt')):
                readfile = open(os.path.join(root, filename), "r")
                d.setdefault(filename, [])
                for line in readfile:
                    m = re.match(combined, line)
                    if m:
                        d[filename].append(m.group(0).rstrip())
                    else:
                        pass
    result = d.copy()
    result.update((k, v) for k, v in d.iteritems() if v is not None)
    print result

当前输出:

{'debug.txt': [], 'logonscript1.vbs': ['strUser = "guytom"', 'strPassword = "P@ssw0rd1"'], 'logonscript2.bat': ['strUsername = "guytom2"', 'strPass = "SECRETPASSWORD"']}

如您所见,我的条目为空值。我想在打印数据之前删除它们。

3 个答案:

答案 0 :(得分:1)

在这部分代码中:

            d.setdefault(filename, [])
            for line in readfile:
                m = re.match(combined, line)
                if m:
                    d[filename].append(m.group(0).rstrip())
                else:
                    pass

您总是将filename添加为字典的关键字,即使您随后未在结果列表中添加任何内容。尝试

            for line in read file:
                m = re.match(combined, line)
                if m:
                    d.setdefault(filename, []).append(m.group(0).rstrip())

只有在确实需要点击d[filename]时才会将append初始化为空列表。

答案 1 :(得分:0)

查看正则表达式(.*)中的第一个匹配组,如果正则表达式匹配但没有匹配的字符,则组(0)为"",而不是无。所以,你可以在那里过滤。

result.update((k, v) for k, v in d.iteritems() if not v)

但你也可以让你的正则表达式为你做那部分。将第一个组更改为(.+),您就不会有空值来过滤掉。

修改

不要在最后删除空值,而是可以避免将它们添加到dict中。

def get_Otherfiles():
    # fixes: make it a raw string so that \s works right and
    # tighten up filtering, ... (U|u) should probably be [Uu] ...
    regs = ["(.+)\s*((U|u)ser(.*))(\s=\s\W\w+\W)", "(.*)((U|u)ser(.*))(\s=\s\w+)", "(.*)((P|p)ass(.*))\s=\s(\W(.*)\W)", "(.*)((P|p)ass(.*))(\s=\s\W\w+\W)"]
    combined = "(" + ")|(".join(regs) + ")"
    cred_results = []
    creds = []
    un_matched = []
    filesfound = []
    d = {}
    for root, dirs, files in os.walk(dir):
        for filename in files:
            if filename.endswith(('.bat', '.vbs', '.ps', '.txt')):
                readfile = open(os.path.join(root, filename), "r")
                # assuming you want to aggregate matching file names...
                content_list = d.get(filename, [])
                content_orig_len = len(content_list)
                for line in readfile:
                    m = re.match(combined, line)
                    if m:
                        content_list.append(m.group(0))
                if len(content_list) > content_orig_len:
                    d[filename] = content_list

答案 2 :(得分:0)

result = dict((k, v) for k, v in d.iteritems() if v is not None)

更新不会删除条目...它只会添加或更改

a = {"1":2}
a.update({"2":7})
print a # contains both "1" and "2" keys