Python:将字符串列表与元组列表进行比较,并根据匹配或不匹配创建新列表。

3

我有一个字符串列表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可以变化长度并且不相等。

我想遍历a,检查“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)] 等等。
我有旧的访问列表规则库,我想通过并替换所有对映射地址的引用,以使用相应的真实地址。
我正在尝试做的事情:
- 遍历访问列表规则。 - 如果找到映射地址匹配项,则修改规则,追加到列表中,并插入一个注释,说明已修改该规则。 - 如果没有找到匹配项,则将现有规则附加到列表中。

1
我认为期望的新列表是错误的,请提供正确的期望输出。 - The6thSense
2
b 不是一个元组列表,而是一个列表的列表。 - Joe T. Boka
1
“a”列表中的“dst6”是打字错误吗?看起来应该是“dest6”。 - Caleb Mauer
是的,打错了。现在已经更正了。 - The Stupid Engineer
1
说实话,我认为你需要重新考虑你正在做的事情。这些不是解决这个问题的正确数据结构。你能否提出一个关于你要解决的问题的问题,而不是询问我们关于你的解决方案?如果你提供更多细节,我认为我们可以更好地帮助你。但这取决于你。 - Caleb Mauer
显示剩余2条评论
2个回答

1

编辑:

既然你说 -

需要在源/目标语句的整个列表中搜索元组列表中的每个元组。

您可以将元素添加到结果列表中,然后在其中找到来自元组的元素时继续替换。例如 -

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结构是用来干什么的。

你可以在for循环的else:部分中添加语句,将未更改的source_dest_statement添加到amended_source_dest_statements中。在第二个for循环内的if部分中,一旦找到匹配项并将更改后的结果添加到列表中,就可以使用break跳出循环。

for循环的else部分仅在正常退出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']

你说得对,我已经编辑了原始问题以反映我想要实现的内容。我已经尝试过for/else语句,但没有使用break语句。 - The Stupid Engineer
这样做会导致元组中的第一个元素不与第一个列表中的其余行进行比较吗?需要在源/目标语句的整个列表中搜索元组列表中的每个元组。 - The Stupid Engineer
哦,好的,那给我一点时间,让我稍微改变一下逻辑。 - Anand S Kumar
嗨,安纳德。对我来说,for else循环最好地解决了问题。我采用了类似这样的东西: - The Stupid Engineer

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']

你走在正确的道路上。如果找不到该值,我需要将原始字符串添加到列表中。这就是我不确定如何构建循环的地方。 - The Stupid Engineer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接