Python技术迷

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 groupby

my_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高级架构师资料合集》。

资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB,全部免费领取。