基于存储在多个python列表中的值的重复检测

2024-10-04 05:32:06 发布

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

我有3个单独的python列表,它们可以根据脚本运行的时间存储变量值,例如:

requestId=[123, 456, 789, 987, 654, 321]
requestTitle=['Title1', 'Title1', 'Title2', 'Title3', 'Title3', 'Title3']
requestBodyText=['BodyText1', 'BodyText1', 'BodyText2', 'BodyText3', 'BodyText3', 'BodyText3']

我需要根据requestTitlerequestBodyText区分哪些请求是重复的,哪些是唯一的(如果请求具有相同的requestTitle和requestBody,那么它是重复的),对于上述内容,它将是:

uniqueList=[123,789,987]
duplicateList=[456, 654, 321]

一旦我知道了这一点,那么我需要将requestID配对,以便将值作为{{}(唯一)和{}(重复)变量传递给我的for loop。我的目标是通过API将所有重复的请求与唯一的请求关联起来

配对后的结果应如下所示:

uniqueIds =[123, 987, 987]
duplicateIds=[456, 654, 321]

987出现两次,因为它有两封重复的电子邮件654和321。因此,它必须运行两次才能关联这两个请求(654和321),请参见以下内容:

emails.py:

HOST = 'https://myUrl.com/path/'

def update_request(request, token, userid):
    headers = {     'accept': 'application/json',
                    'Content-Type': 'application/json',
                    'my-token': token,
                    'User-ID': userid}
    endpoint = 'request/'
    body = {'requestId': x, "addRelatedEmails": [{"id": duplicatedEmailId, "name": "EMAIL"}]}
    return requests.put(url = HOST + endpoint, headers = headers, json=body, verify=False)
    print(r.text)
    return True

for x, y in zip(uniqueIds, duplicateIds):
    update_requests(x, token, userid, duplicatedEmailId=y)

我不确定我在这里描述的上述方法是否可行,但也许有人能够提供帮助或提出更简单的解决方案?提前谢谢

致@Cireo:

requestId=[123, 456, 789, 987, 654, 321]
requestTitle=['Title1', 'Title1', 'Title2', 'Title3', 'Title3', 'Title3']
requestBodyText=['BodyText1', 'BodyText1', 'BodyText2', 'BodyText3', 'BodyText3', 'BodyText3']


from collections import defaultdict
groups = defaultdict(list)  
for i, low, up in zip(requestId, requestTitle, requestBodyText): 
   groups[(low, up)].append(i)

当我调用groups时,我会得到以下结果(这似乎是我目标的一半):

groups
defaultdict(<class 'list'>, {('Title1', 'BodyText1'): [123, 456], ('Title2', 'BodyText2'): [789], ('Title3', 'BodyText3'): [987, 654, 321]})

但现在我需要做以下工作:

uniqueIds = [123, 987, 987] #here I list IDs to my requests that are duplicated. What is important I need to store them as many times as they duplicate. So 123 has one duplicate, 987 has two duplicates therefore I listed this twice.

duplicateIds=[456, 654, 321] #here only the duplicates that I need to relate to my uniqueIds. 

因此,一旦我将uniqueIdsduplicateIds一起传递给我的for循环,它应该与以下内容相关:

请求123与请求456

请求987和请求654

请求987和请求321

我忽略了789号请求,因为它没有副本


Tags: totokenforgroupsrequestidtitle2title1title3
2条回答

@Cireo做对了,除了这部分:

uniq = []
dups = []
for vals in groups.values():
    uniq.append(vals[0])
    dups.extend(vals[1:])

您需要将其更改为:

uniq = []
dups = []
for vals in groups.values():
    for i in range(1, len(vals)):
        uniq.append(vals[0])
        dups.append(vals[i])

之后,您将有两个列表:uniqdups
enter image description here

简化

requestId=[123, 456, 789, 987, 654, 321]
requestTitle=['Title1', 'Title1', 'Title2', 'Title3', 'Title3', 'Title3']
requestBodyText=['BodyText1', 'BodyText1', 'BodyText2', 'BodyText3', 'BodyText3', 'BodyText3']

我们将使值变小,以便在屏幕上显示它们,同时保留关系:

index = [1, 2, 3, 4, 5, 6]
lower = ['a', 'a', 'b', 'c', 'c', 'c']
upper = ['A', 'A', 'B', 'C', 'C', 'C']

您需要一个函数,它接受这三个列表并为您提供

uniq = [1, 4, 4]
dups = [2, 5, 6]

我们已经看到了一个小问题-您是否只希望第一个问题被认为是唯一的?为什么1是唯一的而不是2?一种更通用的方法是根据唯一性将它们分组,然后决定如何处理所有组(例如,选择第一个)

我们将忽略任何有关请求的内容,因为这与您的问题无关

解决方案

您所请求的只是一个简单的分组,我们可以使用dict,将唯一部分作为键:

from collections import defaultdict
groups = defaultdict(list)  # Could be set, but you want order it seems
for i, low, up in zip(index, lower, upper):  # Gives us (1, 'a', 'A'), (2, ...), ...
   groups[(low, up)].append(i)

我们现在有了按唯一性约束分组的ID

>>> dict(groups)
{('a', 'A'): [1, 2], ('b', 'B'): [3], ('c', 'C'): [4, 5, 6]}

由于您希望一个列表中的第一个列表和另一个列表中的其他列表,我们可以提取它们:

uniq = []
dups = []
for vals in groups.values():
    for dup in vals[1:]:
        uniq.append(vals[0])
        dups.append(dup)

>>> uniq
[1, 4, 4]
>>> dups
[2, 5, 6]

请注意,我们将放弃上述内容,因为这只是您实际需要(我们已经有了)的中间步骤:

for vals in groups.values():
   first = vals[0]
   for dup in vals[1:]:
       mark_as_duplicate(first, dup)  # Where this is your api logic

根据评论中的后续问题:

您正在生成一些json以发送到您的请求,如下所示

for first, one_of_rest in zip(stuff):
    body = {'requestId': first, "addRelatedEmails": [{"id": one_of_rest, "name": "EMAIL"}]}
    <do api stuff>

你应该这样做

for vals in groups.values():
   first = vals[0]
   rest = vals[1:]
   if rest:
       related = [{"id": item, "name": "EMAIL"} for item in rest]
       body = {'requestId': first, "addRelatedEmails": related}
       <do api stuff>

相关问题 更多 >