python列表删除算法_关于算法:如何从python中的列表中删除重复的条目

最近在一次采访中,我被要求编写一个python代码来从列表中删除所有重复的条目。

例如:

Input List = {1,2,4,5,2,3,1}

Expected Output List = {4,5,3}

在上面的示例中,1和2出现多次,应将其删除。秩序的保存是很重要的。这就是问题所在。

他又一次不希望我使用内置函数,如set()、unique()等。我猜他是在测试我的算法和ds技巧。他在一开始就讲清楚了。

我想了两种方法。1.)排序(nlog(n)的复杂性)2.)哈希表(排序更快)

哈希表方法:

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

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

if countTable[arr[i]] == 1 :

outList.append(arr[i]);

i+=1

return outList

print rmvAllDuplicate(arr, dataCountTable(arr))

面试官似乎对这个答案没有印象。它让我一直在寻找更好的围裙。我找不到。

如果有人能帮助我改进我的解决方案,或者建议一个新的更好的解决方案,那就太好了!

谢谢!

如果你不介意点菜,就用一套吧

保留编辑顺序是问题的一部分。他不希望我使用像unique()之类的内置函数

stackoverflow.com/questions/7961363/…

另请参阅删除重复项的最快算法。这与您的问题不同,但它是一个很好的基础,可以证明基于哈希的方法在实践中是最快的。

我将使用collection.Counter来实现这一点(或自己实现一个):

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指出的那样,您可以:

result = [x for x, count in Counter(input_list).items() if count == 1]

但在这种情况下,您不能保证保留您的列表的顺序(h/t@dsm)

这具有线性时间复杂性。

最后的清单理解是多余的:singles = [x for x, count in Counter(input_list).items() if count == 1]。

这不是多余的:订单保存很重要。

事实上,对于列表,您可以缩短它;我已经从我脑海中的字典中删除了重复的值;)

这是一个更加简洁/易读/更快一点一点的常量版本,是OP在其编辑中添加的"哈希表方法"…

虽然哈希表的实现可以变得更简洁、易读、更惯用,但速度会稍微提高一点,但我怀疑这并不是你的面试官失望的地方。

更可能的是,他推动你寻求一个更好的解决方案,希望你能提出一个论点,为什么你的解决方案实际上是最佳的,但相反,你搜索了一段时间,放弃了。

所以,这里有很多事情要证明:

这个问题的任何解决方案都必须是O(N)时间。

您的解决方案是(摊销、平均和几乎总是)O(n)时间。

解决方案时间复杂性中的乘数是合理的。

任何解决这个问题的O(n)时间必须是O(m)空间(其中m是不同值的数目)。

您的解决方案是O(M)空间。

解决方案空间复杂性的乘数是合理的。

即使是那些简单的,你也不会在面试中拿出真正严格的证据。其中一些人,你甚至不能提出令人信服的理由,但提出可能的例外,承认你在哪里挥手可能就足够了。例如:

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类。否则,一定要用瓦索夫斯基先生的回答。

但你能自己做同样的事吗?

当然,一个Counter只是一个花哨的dict而已。您可以实现自己的Counter,或者直接执行相同的工作:

input_list = [1,2,4,5,2,3,1]

counts = {}

for value in input_list:

counts.setdefault(value, 0)

counts[value] += 1

现在和他的其他代码一样:

singles = {x for x, count in counts.items() if count == 1}

result = [x for x in input_list if x in singles]

这实际上与您在"哈希表方法"中所做的相同。但它更简洁,更易读,更惯用,更快,一个小但非零常数,所以它可能仍然给面试官留下了更深刻的印象。(当然,所有这些对瓦索夫斯基先生的版本来说都更为真实。)

您可以在一行中理解列表:

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]

我想这是我们所期望的……我对单子的理解不好。

这里的运行时间是多少?如果清点是幼稚的,那就是O(N^2),但如果我错了,请纠正我。

清单理解当然值得学习。

@不可否认的是,这是O(N&178;)。

是-这是O(n^2),因为if in_list.count(num)==1。

尝试:简单

l=[1,2,4,5,2,3,1]

[x for x in l if l.count(x)==1 ]

它将删除所有唯一的项目

为什么要投票????

您的回答(编辑前/编辑后)没有给出预期的输出({4,5,3})

你的答案仍然有错误…结果应该只有[4,5,3],而你的software给[4,5,2,3,1]。

OP希望完全删除任何重复的号码,而不仅仅是删除重复的号码。

希望一切都独一无二,而不是重复,

明白了,我的错没能读懂。

@现在检查代码

您的代码现在非常类似于Figs。解释与代码相反。

类似的是,我使用了内置的count函数,而不是任何额外的变量。

@Hackaholic,都使用了列表理解,list.count方法。只有用于变量的名称不同。

python中的set是一个没有重复项的集合。您可以获取一个列表并删除重复的项目,方法是将其转换为set,然后返回到一个列表:

l = [1,2,3,2,4,3]

l = list(set(l))

print l

output: [1,2,3,4]

是这个答案还是另一个问题?你能解释一下吗?

遍历列表,并为您在列表中看到的特定元素设置一个标记。如果您再次遇到同一个元素,标记将已经设置,您不想再将该元素添加到列表中。这将导致一个线性时间算法。这就是面试官对你的解决方案不满意的原因。哈希实际上也有相同的作用,但您正在为维护哈希表创建一个巨大的重载。

def f(seq):

seen = {}

result = []

for item in seq:

if item in seen: continue

seen[item] = 1

result.append(item)

return result

这只是统一了列表。这不是问题所在。您将给出输出[1, 2, 4, 5, 3],而不是[4, 5, 3]。(同样,用听写来模拟一个场景,而不是仅仅使用一个场景,可能不会给面试官留下太多印象。)

啊,斯纳布迪特把问题读得很好。但你也可以用同样的想法来得到副本。我还以为看到的是一套LOL

是的,在python中,{}不是一个空的集合有点烦人……但是如果它是一个集合,seen[item] = 1将是错误的;它只是seen.add(item)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值