How to remove duplicate entries from a list in python
最近在一次采访中,我被要求编写一个python代码来从列表中删除所有重复的条目。
例如:
1 2 | Input List = {1,2,4,5,2,3,1} Expected Output List = {4,5,3} |
在上面的示例中,1和2出现多次,应将其删除。秩序的保存是很重要的。这就是问题所在。
他又一次不希望我使用内置函数,如set()、unique()等。我猜他是在测试我的算法和ds技巧。他在一开始就讲清楚了。
我想了两种方法。1.)排序(nlog(n)的复杂性)2.)哈希表(排序更快)
哈希表方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | arr = [1,2,4,5,2,3,1] //function : to create a hash table with key = arr[i] & value = occurence count def dataCountTable(arr): countTable = {} i = 0 while i<len(arr) : if arr[i] in countTable : countTable[arr[i]] += 1 else : countTable[arr[i]] = 1 i+=1 return countTable //function : to remove duplicates using the arr & hash table def rmvAllDuplicate(arr, countTable): outList = list() i = 0 while i<len(arr) : if countTable[arr[i]] == 1 : outList.append(arr[i]); i+=1 return outList print rmvAllDuplicate(arr, dataCountTable(arr)) |
面试官似乎对这个答案没有印象。它让我一直在寻找更好的围裙。我找不到。
如果有人能帮助我改进我的解决方案,或者建议一个新的更好的解决方案,那就太好了!
谢谢!
我将使用
1 2 3 4 5 6 7 8 9 | from collections import Counter input_list = [1,2,4,5,2,3,1] # expected_output_list = {4,5,3} # make Counter object for list elements # and pick up to list only those values for which count is 1 singles = {x for x, count in Counter(input_list).items() if count == 1} # filter your list to get only elements that were not duplicates result = [x for x in input_list if x in singles] |
或者正如@forstru指出的那样,您可以:
1 | result = [x for x, count in Counter(input_list).items() if count == 1] |
但在这种情况下,您不能保证保留您的列表的顺序(h/t@dsm)
这具有线性时间复杂性。
虽然哈希表的实现可以变得更简洁、易读、更惯用,但速度会稍微提高一点,但我怀疑这并不是你的面试官失望的地方。
更可能的是,他推动你寻求一个更好的解决方案,希望你能提出一个论点,为什么你的解决方案实际上是最佳的,但相反,你搜索了一段时间,放弃了。
所以,这里有很多事情要证明:
即使是那些简单的,你也不会在面试中拿出真正严格的证据。其中一些人,你甚至不能提出令人信服的理由,但提出可能的例外,承认你在哪里挥手可能就足够了。例如:
- python的
dict 和set 的最坏情况时间为o(n);这只是o(1)的摊余平均情况。您的数据是否有任何可能比O(1)更糟的地方?可能不是,但是……如果这是有人想要做的服务器的一部分,并且他们可以发送他们想要的任何输入数据,那该怎么办? - 他给你的所有值都是小整数。这是真的吗?在这种情况下,不要用口述来计算,只要用
list(range(0, P)) ,其中P 是最大数。然后是O(P)空间,这听起来比O(M)更糟,只是乘数要小得多——列表占空间的1/3(只是值,而不是哈希、键和值),所以如果P << M/3 是一个胜利。这也可能是速度上的胜利,因为不需要保持散列值。你可以更好地使用array.array 。 - python散列表对于存储集合和小计数的dict来说是多余的。自定义哈希表是否可以显著地减少数据量,或者不足以使其值?
我猜如果不允许使用内置函数,也不允许使用stdlib类。否则,一定要用瓦索夫斯基先生的回答。
但你能自己做同样的事吗?
当然,一个
1 2 3 4 5 | input_list = [1,2,4,5,2,3,1] counts = {} for value in input_list: counts.setdefault(value, 0) counts[value] += 1 |
现在和他的其他代码一样:
1 2 | singles = {x for x, count in counts.items() if count == 1} result = [x for x in input_list if x in singles] |
这实际上与您在"哈希表方法"中所做的相同。但它更简洁,更易读,更惯用,更快,一个小但非零常数,所以它可能仍然给面试官留下了更深刻的印象。(当然,所有这些对瓦索夫斯基先生的版本来说都更为真实。)
您可以在一行中理解列表:
1 2 3 | in_list = [1,2,4,5,2,3,1] out_list = [num for num in in_list if in_list.count(num) == 1] # result: [4,5,3] |
尝试:简单
1 2 | l=[1,2,4,5,2,3,1] [x for x in l if l.count(x)==1 ] |
它将删除所有唯一的项目
python中的
1 2 3 4 | l = [1,2,3,2,4,3] l = list(set(l)) print l output: [1,2,3,4] |
遍历列表,并为您在列表中看到的特定元素设置一个标记。如果您再次遇到同一个元素,标记将已经设置,您不想再将该元素添加到列表中。这将导致一个线性时间算法。这就是面试官对你的解决方案不满意的原因。哈希实际上也有相同的作用,但您正在为维护哈希表创建一个巨大的重载。
1 2 3 4 5 6 7 8 | def f(seq): seen = {} result = [] for item in seq: if item in seen: continue seen[item] = 1 result.append(item) return result |