Python面试题:如何去掉列表、元祖中的重复元素,去重
今天我们来聊聊Python中的一个常见问题:如何去掉列表和元组中的重复元素。听起来是个简单的操作,但要用代码实现,涉及到的细节和方法还是不少的。
作为一个程序员,解决这个问题有很多种方式,接下来我会分享几种常见的解决方法,并讲解每种方法的优缺点,帮助大家更好地掌握这道面试题。
1. 使用集合 set 去重
先来聊聊最常见的方法——使用集合(set)。Python中的集合是一种无序且不允许重复的容器,因此,我们可以利用这一点来去掉列表和元组中的重复元素。
对列表去重
my_list = [1, 2, 3, 4, 5, 1, 2, 6]
my_list = list(set(my_list))
print(my_list)
解释:
首先,我们把列表转换成集合( set)。集合会自动去掉重复元素,剩下的就是没有重复的元素。然后,我们将去重后的集合转换回列表(因为题目要求的是列表)。
优缺点:
优点:这种方法简洁,代码量少,效率高。 缺点:集合是无序的,因此会丢失原来列表中的顺序。如果顺序不重要,这种方法是很合适的。如果需要保留顺序,那就不太合适了。
对元组去重
my_tuple = (1, 2, 3, 4, 5, 1, 2, 6)
my_tuple = tuple(set(my_tuple))
print(my_tuple)
解释:
和列表类似,元组也是可以转换成集合的,但集合同样会丢失原有的顺序。最后,再将集合转回元组。
优缺点:
这和列表去重一样,也存在顺序丢失的问题。
2. 使用字典的 fromkeys 方法
如果你想去重的同时保留元素的顺序,可以考虑使用字典的 fromkeys() 方法。Python中的字典从Python 3.7开始保证了插入顺序,这对于我们需要保留顺序的场景来说,十分有用。
对列表去重(保持顺序)
my_list = [1, 2, 3, 4, 5, 1, 2, 6]
my_list = list(dict.fromkeys(my_list))
print(my_list)
解释:
dict.fromkeys()方法会将列表中的元素作为字典的键,而字典的键是唯一的,所以重复的元素会被去掉。使用 list()函数将字典的键转换回列表。
优缺点:
优点:保留了元素的顺序,同时也去掉了重复元素。 缺点:如果你的数据结构有很多元素,转换成字典会占用更多的内存。对于小规模的数据集来说,这并不算问题。
对元组去重(保持顺序)
my_tuple = (1, 2, 3, 4, 5, 1, 2, 6)
my_tuple = tuple(dict.fromkeys(my_tuple))
print(my_tuple)
解释:
使用 dict.fromkeys()方法去重后,再将其转换回元组。
优缺点:
同样保留了顺序,但转换为字典也有一定的开销。
3. 使用列表推导式
有时候,你可能不希望将整个数据结构转换为其他类型,而是想利用原本的结构来去重。此时,使用列表推导式可能会更加灵活,尤其是当你有自定义的去重逻辑时。
对列表去重(保持顺序)
my_list = [1, 2, 3, 4, 5, 1, 2, 6]
seen = set()
my_list = [x for x in my_list if x not in seen and not seen.add(x)]
print(my_list)
解释:
通过 seen集合记录已经出现过的元素。对于每一个元素,如果它没有在 seen中出现过,就把它添加到结果列表里,并将其加入seen集合。
优缺点:
优点:这种方法非常灵活,能保留顺序,并且效率相对较高。 缺点:相对来说,代码稍微复杂一点,适合有特定需求的场景。
4. 使用 itertools.groupby 去重
itertools.groupby() 方法通常用来对排序后的数据进行分组,但是它也能用来去重。注意,这个方法要求数据已经排序过。
对列表去重(保留顺序)
from itertools import groupbymy_list = [1, 2, 3, 4, 5, 1, 2, 6]
my_list.sort()
my_list = [key for key, _ in groupby(my_list)]
print(my_list)
解释:
首先,我们对列表进行了排序。 然后,使用 groupby()来将相同的元素分到一起,并提取每一组的第一个元素。
优缺点:
优点:能保留顺序,而且可以很方便地处理排序后的数据。 缺点:要求数据已排序。如果数据量较大或者排序的代价较高,就不适用。
5. 手动遍历去重
最后一种方法是手动遍历列表,逐个元素检查是否已经出现过。这种方法虽然效率稍低,但却非常直观,适合用在一些特殊场景中。
对列表去重(保留顺序)
my_list = [1, 2, 3, 4, 5, 1, 2, 6]
new_list = []
for item in my_list:
if item not in new_list:
new_list.append(item)
print(new_list)
解释:
这里我们手动遍历列表中的每个元素,并将尚未出现过的元素加入新列表中。
优缺点:
优点:非常直观,适合初学者理解。 缺点:效率较低,尤其是当列表较长时, item not in new_list会造成不必要的重复查找,导致性能问题。
总结
通过上面的介绍,我们了解了几种常见的去重方法,每种方法都有其适用场景。如果不需要保持顺序,使用集合(set)是最简洁高效的方式;如果需要保持顺序,dict.fromkeys() 或者列表推导式是不错的选择;而 itertools.groupby() 适合处理已经排序的数据。
每种方法都有其优缺点,所以根据实际情况,选择合适的方法才是最重要的。至于那些需要保留顺序的场景,我个人觉得,dict.fromkeys() 和列表推导式的方式最为优雅,既高效又能保留顺序。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。