在python 3中消除二维数组中的重复条目

时间:2018-02-20 18:42:41

标签: python arrays python-3.6 nested-lists

我不确定这是否是解决问题的最佳方式 - 我很新,所以我会给你一些背景知识:

我设法创建了一个程序,可以为我搜索一些网站,并根据特定标准向我返回天气报告。它们中的一些非常相似,如果不相同的话,仍然可以滚动浏览同一地区的十几个报告。更有用的是,如果我可以将这些报告合并为一个,同时添加每个报告中的标题。

到目前为止,我的计划所做的是将每个报告细分为:

  • 标题
  • 警告类型
  • 正文

这些被推入一个更大的数组,一维的长度为[x],另一维的长度为[3]。

我的想法是,如果我可以遍历数组并比较每个的正文。如果正文文本不同,它会传递给它,但如果它们相同,我的程序可以将标题添加到下一个,然后完全删除该条目。

结果不如恒星。我已经尝试了几种不同的混合结果方式,但这就是我目前所拥有的:

#Overall array as list
practice_array = []

#Sub lists
first_array = ["header 1", "warning", "body"]
second_array = ["header 2", "warning", "body"]
third_array = ["header 3", "warning", "body"]
fourth_array = ["header 4", "warning", "body"]
fifth_array = ["header 5", "warning", "body"]

#Values of practice_array
practice_array = [first_array, second_array, third_array, fourth_array,
fifth_array]

#Length of the loop
length = len(practice_array)

#Loop starts with the first item in the list 
for x in range(0, length):

    #The second loop starts with the next so it has something to compare
    for y in range(1, length):

        #If the body texts are the same then...
        if practice_array[x][2] == practice_array[y][2] :

             #Add the header to the other header
             practice_array[y][0] += (' ' + practice_array[x][0])

             #Delete the first item
             del practice_array[x]

             #Print for me to see
             print(practice_array[y][0])

IndexError:列表索引超出范围

5 个答案:

答案 0 :(得分:0)

您的算法正在检查每个条目,并将其与其他所有条目进行比较。这将给你O(n ^ 2)的性能。您可以通过首先对文本字段进行排序将其降低到O(n)性能。然后,您只需要比较每对连续的条目。

答案 1 :(得分:0)

for i in range(len(practice_array)):
    if len(practice_array[i]) == 0:
            continue
    for j in range(1, len(practice_array)):
        if len(practice_array[j]) == 0:
            continue
        if i != j and practice_array[i][2] == practice_array[j][2]:
            practice_array[i][0] += " {}".format(practice_array[j][0])
            practice_array[j] = []
practice_array = list(filter(lambda x: len(x) > 0, practice_array))

这是你应该怎么做的。您绝不能从您正在处理的列表中删除项目,更不用说将其长度存储在变量中并将其用作条件(当实际长度减少时)。比较后,只需使用相同的body替换每个内部列表,其中包含一些简单的内容,但不会通过过滤条件,因此您只需选择所需的项目即可更新结果列表(例如:我们&#39 ;重新使用空列表替换具有相同body的列表,以便我们稍后可以将其过滤掉。)

答案 2 :(得分:0)

IndexError是因为您在删除并尝试在后验迭代中访问超出范围的元素时更改列表大小。

这是我认为你想做的一个可能的解决方案

# Get all different body values
unique_body = set([i[2] for i in practice_array])

result = []
# Iterate over body values
for body in unique_body:
    # Get all entries have the same body value
    matching_entries = [i for i in practice_array if i[2] == body]

    # Join the headers
    header = ' '.join([i[0] for i in matching_entries])

    # Make a new entry and append it to a result list
    merged_entry = [header, matching_entries[0][1], body]
    result.append(merged_entry)

答案 3 :(得分:0)

使用字典构造结果很容易实现,并且您获得O(n)时间复杂度。 我希望我能正确理解你想要达到的目标。

practice_dict = {}
for p in practice_array:
    body = p[2]
    if body in practice_dict:
        practice_dict[body][0] += (' ' + p[0])
    else:
        practice_dict[body] = p

print(practice_dict)

输出:

{'body': ['header 1 header 2 header 3 header 4 header 5', 'warning', 'body']}

您也可以使用列表,但它不太方便

答案 4 :(得分:0)

您正在获取索引错误,因为您正在更改" practice_array"的大小。虽然循环了它的内容,但你可能已经知道了。

要利用内置函数速度,您可以将practice practice_array转换为集合并返回到new_array_1 = list(set(practice_array))的列表中。这假设您不关心列表的顺序,这只会消除相同的数组。

无论是否进行set()转换,您都可以累积具有唯一" body"的数组。元素(标题和警告是否相同),在新列表中,如果" body"列表的元素在累积" body"的列表中找不到。元件。

new_array_2 = []
body_els = []

for el in new_array_1:
    if el[2] in body_els:
        pass
    else:
        new_array_2.append(el)
        body_els.append(el[2])

在循环结束时,new_array_2将是具有唯一主体元素的数组列表。