【问题标题】:Python: Iterate through list and remove duplicates (without using Set())Python:遍历列表并删除重复项(不使用 Set())
【发布时间】:2017-04-26 01:02:08
【问题描述】:

所以我有一个清单:

s = ['cat','dog','cat','mouse','dog']

我希望能够遍历列表并删除重复项,而不使用 set() 函数!因此,例如,它应该删除 'cat' 和位置 s[2],但将 'cat' 保留在位置 s[0]。然后它需要为“狗”做同样的事情,即。将 'dog' 保留在位置 s[1] 但从位置 s[4] 移除 'dog'。

所以输出是:

s = ['cat','dog','mouse']

我尝试使用 i 和 j 作为列表中的索引位置,并检查位置 i 处的元素是否等于位置 j 处的元素。如果是,它将删除它并将 j 的值增加 1,如果不是,那么它将离开它并仅增加 j 的值。在整个列表被迭代之后,它将增加 i 的值,然后再次检查整个列表,寻找新元素。下面:

i = 0
j = 1
for a in range(len(s)):
    for b in range(len(s)):
        if s[i] == s[j]:
            s.remove(s[j])
            j = j + 1
        else:
            j = j + 1
    i = i + 1

我在这里做错了什么?

【问题讨论】:

  • 使用 in 代替 ==。如果该数组中不存在该值,则将它们存储在单独的数组中。
  • 您是否有任何理由需要更新列表而不是创建新列表? l = []; for e in s: if e not in l: l.append(e)
  • 另一个问题是您正在遍历所有索引直到列表末尾。如果确实有任何重复,那么当您到达那里时,列表会变短,并且您将收到 IndexError。
  • 你为什么不用set

标签: python list


【解决方案1】:

问题在于“自动” for 循环 - 在修改您正在迭代的内容时,您必须小心使用它们。这是正确的解决方案:

def remove_dup(a):
   i = 0
   while i < len(a):
      j = i + 1
      while j < len(a):
         if a[i] == a[j]:
            del a[j]
         else:
            j += 1
      i += 1

s = ['cat','dog','cat','mouse','dog']
remove_dup(s)
print(s)

Output: ['cat', 'dog', 'mouse']

这个解决方案是就地的,修改原始数组而不是创建一个新数组。它也没有使用任何额外的数据结构。

【讨论】:

  • 谢谢伙计!正在考虑使用while循环,在第一个while之后错过了关于j的部分,并且list.remove()对我不起作用!谢谢!
  • 为我返回无。 List = ['94. / Date: 16 Feb, 2022 ', '95. / Date: 16 Feb, 2022 ', '96. / Date: 16 Feb, 2022 ', '97. / Date: 16 Feb, 2022 ', '98. / Date: 16 Feb, 2022 ', '99. / Date: 16 Feb, 2022 ', '100. / Date: 16 Feb, 2022 ', '101. / Date: 16 Feb, 2022 ', '102. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ', '103. / Date: 18 Feb, 2022 ']
  • 请检查您是否准确复制了代码,并且按照我的演示使用它。是的,该函数返回None:请注意,该函数是一个修改器函数,可以就地修改列表,如上所述。此外,我建议不要使用像 List 这样的变量名称,因为它与内置关键字 list 非常接近(如果您使用类型库,它是一个关键字)。
【解决方案2】:

您可以遍历列表并检查是否已经添加了动物。

s = ['cat','dog','mouse','cat','horse','bird','dog','mouse']

sNew = []
for animal in s:
    if animal not in sNew:
        sNew.append(animal)

s = sNew

【讨论】:

  • 除了“不在”还有其他选择吗?我的任务的目的是了解排序算法是如何工作的,所以我猜“不在”是一种作弊。
【解决方案3】:

您不应该在迭代列表时更改列表,您可能会跳过元素或获得IndexError。如果您不能使用set,请使用collections.OrderedDict

>>> from collections import OrderedDict

>>> s = ['cat','dog','cat','mouse','dog']

>>> list(OrderedDict.fromkeys(s).keys())
['cat', 'dog', 'mouse']

【讨论】:

  • 不是 OP,但感谢您的回答。我正在尝试理解您的代码。所以你可以使用OrderedDict,因为列表可以被视为只有键但没有值的字典? 'fromkeys' 有什么作用?谢谢。
  • @BowenLiu fromkeys 使用指定的键创建字典。我使用了一个有序的字典,因为它是有序的并删除了重复的键,我们不关心字典的值 - 但是没有内置的有序集......
  • 非常感谢您的解释和介绍这种新方法。我不知道您可以创建没有与每个键对应的值的字典。谢谢。
  • 请注意,在现代 Python(CPython/PyPy 3.6 和任何 Python 3.7+)中,您可以只使用dict.fromkeys,它会在启动时运行得更快(dict 是插入排序的,@987654330 @ 不是必需的,除非您依赖更改顺序的方法或顺序敏感的比较)。也无需调用.keys()(在任何版本的 Python 上); dicts 已经是其键的可迭代对象,因此 list(dict.fromkeys(s)) 就足够了。
【解决方案4】:

这是一个单一的解决方案:

s = ['dog', 'cat', 'cat', 'mouse', 'dog']   

answer = [animal for idx, animal in enumerate(s) if a not in s[:idx]]

你会看到:

>>> answer
['cat', 'dog', 'mouse']

【讨论】:

    【解决方案5】:

    我不确定您为什么不使用集合,但这里有一个替代方案。遍历您的原始列表,如果每个元素尚未在新列表中,则将其放入新列表中。示例:

    l = []
    s = ['dog', 'cat', 'cat', 'mouse', 'dog']
    
    for i in range(len(s)):
        if s[i] not in l:
            l.append(s[i])
    

    现在:

    >>> s
    ['dog', 'cat', 'mouse']
    

    【讨论】:

    • 更规范的只是迭代列表 s 与索引。
    • 非常正确。它可能更 Pythonic。
    • 除了“不在”还有其他选择吗?我的任务的目的是了解排序算法是如何工作的,所以我猜“不在”是一种作弊。
    【解决方案6】:
    s = ['cat','dog','cat','mouse','dog']
    duplicates = []
    
    for animal in s:
      if s.count(animal) > 1:
        if animal not in duplicates:
          duplicates.append(animal)
    print(duplicates)
    

    【讨论】:

    • 如果您解释了您提供的代码如何回答问题,这将是一个更好的答案。
    • 这并没有增加其他答案尚未涵盖的内容,实际上是错误的,因为它不会保留任何内容除非重复(它确实将重复减少到单个副本,但消除非重复是错误的)。例如,对于 OP 的情况,他们希望看到 'mouse' 作为结果中的最后一个元素,但您将其排除在外,因为它只出现一次。
    【解决方案7】:

    这里只是通过类型转换,

    s = ['cat','dog','cat','mouse','dog']
    
    l = list(set(s)) 
    
    print(l)
    

    【讨论】:

    • OP的问题明确排除了set的使用;如果他们没有,那很好,但这也非常明显(问题中的限制是为什么没有其他人发布它)。
    猜你喜欢
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 2011-11-30
    • 2010-11-24
    • 2016-03-24
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多