Python 替换列表中的元素

Python substitute elements inside a list

我有以下过滤和打印列表的代码。最终输出为json,形式为name.example.com。我想用 name.sub.example.com 代替它,但实际上我很难做到这一点。 filterIP 是一段有效的代码,可以完全删除元素,我一直在尝试重新使用该代码来修改元素,它不必以这种方式处理。

def filterIP(fullList):
    regexIP = re.compile(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$')
    return filter(lambda i: not regexIP.search(i), fullList)

def filterSub(fullList2):
    regexSub = re.compile(r'example\.com, sub.example.com')
    return filter(lambda i: regexSub.search(i), fullList2)

groups = {key : filterSub(filterIP(list(set(items)))) for (key, items) in groups.iteritems() }

print(self.json_format_dict(groups, pretty=True))

这是我在没有 filterSub 的情况下得到的结果

"type_1": [
    "server1.example.com",
    "server2.example.com"
],

这就是我用 filterSub 得到的结果

"type_1": [],

这就是我想要得到的

"type_1": [
    "server1.sub.example.com",
    "server2.sub.example.com"
],

声明:

regexSub = re.compile(r'example\.com, sub.example.com')

并不像您认为的那样。它创建一个已编译的正则表达式,匹配字符串 "example.com" 后跟一个逗号、一个 space、字符串 "sub"、一个任意字符、字符串 "example"、一个任意字符, 和字符串 "com"。它不会创建任何类型的替换。

相反,您想这样写,使用 re.sub 函数执行替换并使用 map 应用它:

def filterSub(fullList2):
    regexSub = re.compile(r'example\.com')
    return map(lambda i: re.sub(regexSub, "sub.example.com", i),
               filter(lambda i: re.search(regexSub, i), fullList2))

如果示例都真的像您列出的示例一样简单,那么正则表达式可能有点矫枉过正。一个简单的解决方案是使用字符串 .split.join。这可能会提供更好的性能。

首先在第一期拆分url:

url = 'server1.example.com'
split_url = url.split('.', 1)  
# ['server1', 'example.com']

然后你可以使用sub重新加入url:

subbed_url = '.sub.'.join(split_url)
# 'server1.sub.example.com'

当然你可以同时进行拆分和合并

'.sub.'.join(url.split('.', 1))

或者创建一个简单的函数: def sub_url(url): return '.sub.'.join(url.split('.', 1))

要将此应用于列表,您可以采用多种方法。

列表理解:

subbed_list = [sub_url(url)
               for url in url_list]

映射它:

subbed_list = map(sub_url, url_list)

或者我最喜欢的发电机:

gen_subbed = (sub_url(url)
               for url in url_list)

最后一个看起来像列表推导式,但提供了额外的好处,即您无需重建整个列表。它在迭代生成器时一次处理一个项目的元素。如果你决定以后确实需要这个列表,你可以简单地将它转换为一个列表,如下所示:

subbed_list = list(gen_subbed)