当两个列表中都有基于索引的匹配项时,如何解码一个列表并从中删除项?

2024-03-28 17:02:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个列表,其中包含以下类型的信息

List #1:
Request_List = ["1/1/1.34", "1/2/1.3.5", "1/3/1.2.3", ...same format elements]
List #2:
Reply_List = ["1/1/0", "1/3/1", "1/2/0", ...same format elements]

从“回复”列表中,我希望能够比较“#/#/#”中的第二项,在这种情况下,它将是1、3、2,依此类推,与回复列表中的所有项进行比较,并检查是否与“请求列表”中的第二项相匹配。如果存在匹配项,那么我希望能够返回一个新的列表,其中包含请求字符串中第三个索引的信息,并在回复中附加匹配字符串的第三个索引

The result would be like the following. 
Result = ["1.34.0", "1.3.5.0", "1.2.3.1"] 

请注意,0被附加到1.34中,1被附加到1.3.4中,0被附加到1.2.3中,“Reply”列表中相应的索引中,作为“Reply”列表中存在的第二个索引。“回复”列表可以将项目放在列表中的任何位置

解决上述问题的代码如下所示

def get_list_of_error_codes(self, Reply_List , Request_List ):
        decoded_Reply_List = Reply_List .decode("utf-8")  # I am not sure if this is 
                                           the right way to decode all the elements in the list? 

        Result = [
            f"{i.split('/')[-1]}.{j.split('/')[-1]}"
            for i in Request_List 
            for j in decoded_Reply_List
            if (i.split("/")[1] == j.split("/")[1])
        ]
        return Result
res = get_list_of_error_codes(Reply_List , Request_List)
print (res) # ["1.34.0", "1.3.5.0", "1.2.3.1"] 

我现在面临的问题:

  1. 我不确定我是否以正确的方式解码了Reply_List。有人能帮我核实一下吗

  2. 我不确定在根据条件if (i.split("/")[1] == j.split("/")[1])找到匹配项时,如何删除Reply_ListRequest_List的相应项


Tags: the字符串in信息format列表ifrequest
1条回答
网友
1楼 · 发布于 2024-03-28 17:02:59
  1. 您可以使用列表理解来解码列表:

decoded_Reply_List = [li.decode(encoding='utf-8') for li in Reply_List]

  1. 在这种情况下,如果您想在创建新列表时也从列表中删除项目,我认为列表理解不是正确的做法。只需使用嵌套for循环:
def get_list_of_error_codes(self, Reply_List, Request_List):
    decoded_Reply_List = [li.decode(encoding='utf-8') for li in Reply_List]

    Result = []
    for i in list(Request_List):
        for j in decoded_Reply_List:
            if (i.split("/")[1] == j.split("/")[1]):
                Result.append(f"{i.split('/')[-1]}.{j.split('/')[-1]}")
                Reply_List.remove(j)
                break
        else:
            continue
        Request_List.remove(i)
    return Result

Request_List = ["1/1/1.34", "1/2/1.3.5", "1/3/1.2.3"]
Reply_List = [b"1/1/0", b"1/3/1", b"1/2/0"]
print(get_list_of_error_codes("Foo", Reply_List, Request_List))

# Output: ['1.34.0', '1.3.5.0', '1.2.3.1']            

需要注意的事项: 我添加了一个break,这样在找到匹配项时就不会继续寻找。它将只匹配第一对,然后继续

for i in list(Request_List)中,我添加了list()强制转换来有效地复制列表。这允许我们从Request_List中删除条目,而不会中断循环。我不是为for j in decoded_Reply_List做这个的,因为它已经是Reply_List的副本了(我假设您想从Reply_List中删除条目

最后是else: continue。如果找不到匹配项,我们就不想接触Request_List.remove(i)。如果break被调用,else将不会被调用,这意味着我们将到达Request_List.remove(i)。但是如果循环在没有找到匹配项的情况下完成,那么循环将进入else,我们将通过调用continue跳过删除步骤

编辑:

实际上,Reply_List.remove(j)中断,因为我们在这个方法中解码了j,因此解码的jReply_List中的对象不同。下面是一些可以解决这个问题的修订代码:

def get_list_of_error_codes(Reply_List, Request_List):
    # decoded_Reply_List = [li.decode(encoding='utf-8') for li in Reply_List]

    Result = []
    for i in list(Request_List):
        for j in list(Reply_List):
            dj = j.decode(encoding='utf-8')
            if (i.split("/")[1] == dj.split("/")[1]):
                Result.append(f"{i.split('/')[-1]}.{dj.split('/')[-1]}")
                Reply_List.remove(j)
                break
        else:
            continue
        Request_List.remove(i)
    return Result

Request_List = ["1/1/1.34", "1/2/1.3.5", "1/3/1.2.3"]
Reply_List = [b"1/1/0", b"1/3/1", b"1/2/0"]
print("Result: ", get_list_of_error_codes(Reply_List, Request_List))
print("Reply_List: ", Reply_List)
print("Request_List: ", Request_List)

# Output:
# Result:  ['1.34.0', '1.3.5.0', '1.2.3.1']
# Reply_List:  []
# Request_List:  []

我所做的不是创建一个单独的解码列表,而是在循环时对条目进行解码,然后从Reply_List中删除未解码的条目。这也应该更有效一点,因为我们现在不再循环Reply_List两次了

相关问题 更多 >