我有一个字符串列表a和一个元组列表b,其中:
a=['from src1 to dest2','from src3 to dest4','from src5 to dest6']
b=[['destb','dest2'],['destd','loc4'],['destf','dest6'],['desth','dest8']]
a和b的长度可能不同而且不相等。
我想迭代一下,检查是否' dest'匹配每个元组中的第一个字符串,如果是,则将其替换为第二个字符串,并将其附加到新列表中。如果找不到匹配项,我想将字符串未更改地附加到列表中。
所以看起来应该是这样的:
newlist=['from src1 to destb','from src3 to destd','from src5 to destf']
我目前的代码如下:
for source_dest_statement in source_dest_statements:
for i,j in in source_dest_tuple:
if j in source_dest_statement:
amended_source_dest_statements.append('SOMETHING HAS CHANGED!')
amended_source_dest_statements.append(re.sub(j,i,source_dest_statement))
else:
amended_source_dest_statements.append(source_dest_statement)
正如预期的那样,当没有匹配时,这会重复附加当前迭代的source_dest_statement,当我需要它们时,它们只出现在原始列表中的次数。解决此问题的最简单方法是什么?
编辑:我将尝试解释我试图解决的问题:
我有一个防火墙配置,它有许多NAT语句。这些语句在更新的代码版本中已更改,因此在目标地址使用映射地址的情况下,它们现在使用实际地址。
我的元组列表是映射地址对的实际地址列表。所以像[(realaddress1,mappedaddress1),(r2,m2),(r3,m3)]等等。
我有旧的访问列表规则库,我想通过它,并将所有对映射地址的引用替换为相应的实际地址。
我想做的事情: - 迭代访问列表规则。 - 如果找到映射的地址匹配,则修改规则,附加到列表,插入注释,说明规则已被修改。 - 如果未找到匹配项,请将现有规则附加到列表中。
for / else语句解决了我的问题。所以它看起来像这样: 对于某些列表中的currline: for i,j in sometuple: 如果j在currline中: newlistoflines.append(应用re.sub(J,I,currline)) 打破 其他: newlistoflines.append(currline)
感谢您的帮助!我现在知道休息声明不是邪恶的,但我仍然想知道是否有更优雅的方法来解决我的问题。
答案 0 :(得分:1)
编辑:
因为你说 -
需要在整个source / dest语句列表中搜索元组列表中的每个元组。
您可以将元素添加到结果列表中,然后在元组中找到元素时继续替换它。示例 -
for source_dest_statement in source_dest_statements:
amended_source_dest_statements.append(source_dest_statement)
for i,j in in source_dest_tuple:
if j in amended_source_dest_statements[-1]:
amended_source_dest_statements[-1] = re.sub(j,i,amended_source_dest_statements[-1])
演示 -
>>> import re
>>> a=['from src1 to dest2','from src3 to dest4','from src5 to dest6']
>>> b=[['destb','dest2'],['destd','loc4'],['destf','dest6'],['desth','dest8']]
>>> result = []
>>> for x in a:
... result.append(x)
... for i,j in b:
... if j in result[-1]:
... result[-1] = re.sub(j,i,result[-1])
...
>>> result
['from src1 to destb', 'from src3 to dest4', 'from src5 to destf']
以前的答案:
这就是for..else
构造的用途。
您可以在source_dest_statement
循环的amended_source_dest_statements
部分添加语句,将未更改的else:
添加到for
。在第二个if
循环内的for
部分中,找到匹配后可以break
并将更改后的结果添加到列表中。
else
循环的for
部分仅在正常退出for
循环时执行,而不使用break
语句,因此会出现这种情况。你找不到任何比赛。示例 -
for source_dest_statement in source_dest_statements:
for i,j in in source_dest_tuple:
if j in source_dest_statement:
amended_source_dest_statements.append(re.sub(j,i,source_dest_statement))
else:
amended_source_dest_statements.append(source_dest_statement)
另外,正如评论中所解释的那样,b
不是元组列表,它是列表列表(虽然对于您的特定用例并不重要)。
演示 -
>>> a=['from src1 to dest2','from src3 to dest4','from src5 to dst6']
>>> b=[['dest2','destb'],['dest4','locd'],['dest6','destf'],['dest8','desth']]
>>> result = []
>>> for x in a:
... for i,j in b:
... if i in x:
... result.append(re.sub(i,j,x))
... break
... else:
... result.append(x)
...
>>> result
['from src1 to destb', 'from src3 to locd', 'from src5 to dst6']
答案 1 :(得分:1)
如果在b [0]中找到a中的目的地,则将b [1]代入a,并将新字符串添加到结果中。如果我们没有完成替换,则输出原始内容。
result = []
for source in a:
# Do all replacements with a list-comprehension
replacements = [source.replace(old,new) for old, new in b if old in source]
# If replacements we're done add the replacements else add the source
if replacements:
result.extend(replacements)
else:
result.append(source)
在测试输入上输出:
['from src1 to destb', 'from src3 to locd', 'from src5 to destf']