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)
我有以下过滤和打印列表的代码。最终输出为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)