面试python开发岗,经常会碰到这样一道面试题,列表去重问题。其在爬虫项目中会得到广泛应用。下面列出几个方法:
1. 利用集合元素唯一性的性质:
def DelDupli(L): return list(set(L))L = [1,3,3,3,4,3,34,3,54,3,4,2,8]print(DelDupli(L))# result[1, 34, 3, 4, 2, 8, 54]2. 创建一个新列表,判断原列表中的每个元素是否在新列表中,不在的话追加即可:
def DelDupli2(L): lst = [] # 空间复杂度会增加 for x in L: if x not in lst: lst.append(x) return lstL = [1,3,3,3,4,3,34,3,54,3,4,2,8]print(DelDupli2(L))# result[1, 3, 4, 34, 54, 2, 8]3. 利用字典“键”的唯一性解决该问题:
def DelDupli3(L): myDict = {} for i in L: myDict[i] = 0 L = list(myDict.keys()) return LL = [1,3,3,3,4,3,34,3,54,3,4,2,8]print(DelDupli3(L))# result[1, 3, 4, 34, 54, 2, 8]上面方法2和方法3都需要创建新对象,如果数据量过大,会增加算法的空间复杂度,不可取。
4. 遍历列表,统计当前元素在列表中的个数,若大于1,则去除:
def DelDupli4(L): for i in L: if L.count(i) > 1: L.remove(i) return LL = [1,3,3,3,4,3,34,3,54,3,4,2,8]print(DelDupli4(L))# result[1, 4, 34, 54, 3, 4, 2, 8]【注意】该方法是一个典型错误!
i 相当于是按照列表的下标来取值,每循环完一次,下标 i 会自动加1,这样便会跳过一些元素的判断,从而导致错误。
可附加一些调试信息,这样看的会更清楚一点:
def DelDupli4(L): for i in L: print('L ---> ', L) print('i ---> ', i) if L.count(i) > 1: L.remove(i) return LL = [1, 3, 3, 3, 4, 3, 34, 3, 54, 3, 4, 2, 8]print(DelDupli4(L))# resultL ---> [1, 3, 3, 3, 4, 3, 34, 3, 54, 3, 4, 2, 8]i ---> 1L ---> [1, 3, 3, 3, 4, 3, 34, 3, 54, 3, 4, 2, 8]i ---> 3L ---> [1, 3, 3, 4, 3, 34, 3, 54, 3, 4, 2, 8]i ---> 3L ---> [1, 3, 4, 3, 34, 3, 54, 3, 4, 2, 8]i ---> 3L ---> [1, 4, 3, 34, 3, 54, 3, 4, 2, 8]i ---> 3L ---> [1, 4, 34, 3, 54, 3, 4, 2, 8]i ---> 3L ---> [1, 4, 34, 54, 3, 4, 2, 8]i ---> 2L ---> [1, 4, 34, 54, 3, 4, 2, 8]i ---> 8[1, 4, 34, 54, 3, 4, 2, 8]5. 为解决上述问题,其实也很简单,只需将 if 语句变成 while 语句即可。使用 while 可循环判断当前下标的元素个数是否大于1,这样便不会导致跳过某个元素的情况发生。
def DelDupli5(L): for i in L: while L.count(i) > 1: L.remove(i) return LL = [1,3,3,3,4,3,34,3,54,3,4,2,8]print(DelDupli5(L))# result[1, 34, 54, 3, 4, 2, 8]