删除差异但保留python列表中的顺序和重复

时间:2016-11-26 21:35:16

标签: python python-3.x

使用版本3.x - 想要了解最简单和本地的方法来解决以下问题:

示例列表:

listA = [1, 2, 3, 66, 0]
listB = [0, 0, 1, 2, 3, 66, 0, 99, 0, 3]

如何删除2个列表之间的差异,以便新的listC与listA完全相同且具有完全相同的顺序?

因此,使用上面的示例,listC应该等于[1, 2, 3, 66, 0]

列表A可能比列表B大,另一个条件是列表A永远不会有重复数字,而不像列表B可能有重复项。

我试图解决的慈善俱乐部运动是:

Linday的大脑测试:

如果B中的元素按照它们出现在B中的顺序出现在A中但是不一定连续出现,请编写一个打印'YES'的程序。否则程序应打印“否”。

Linday的奖金测试:

如果B中的元素出现在A中,请编写打印'YES'的程序 命令它们连续出现在B中。

显然,如果有人喜欢挑战,那么请发布完整的程序来解决这两个问题。

2 个答案:

答案 0 :(得分:1)

另一种略微欺骗的方法是使用in运算符的字符串。如果将每个列表转换为字符串,则可以快速查看A是否是B的子字符串,顺序为连续

def aInB(listA, listB):
    str_a = "," + ",".join([str(c) for c in listA]) + ","
    # ',1,2,3,66,0,'
    str_b = "," + ",".join([str(c) for c in listB]) + ","
    # ',0,0,1,2,3,66,0,99,0,3,'

    return str_a in str_b
# True

现在这只有在A的​​长度小于B时才有效,但根据问题的定义,听起来总是如此。由于@stefanpochmann在评论中指出了问题,额外的逗号是必要的。

让它打印“是”和“否”非常简单:

if aInB(listA, listB):
   print("YES")
else:
   print("NO")

对于非连续方法,我认为你必须采用其中一种迭代方法。这个解决方案只是提供了另一种思考方式是“A in B”。

编辑:我无法自拔,所以这里的互动方式可能有些过分,但也许你会发现它更容易理解(你永远不知道)。

def aInB(listA, listB):
   # if listA is empty, don't even bother
   if not listA:
      return False

   # build a dictionary where each key is a character in listA
   # and the values are a list containing every index where that character
   # appears in listB
   occurences = {c:[i for i,e in enumerate(listB) if e==c] for c in listA}

   # now we are going to walk through listA again
   # but this time we are going to use our `occurences` dictionary
   # to verify that the elements appear in order
   last_index = 0
   for i,e in enumerate(listA):
     # if the character `e` never appears in listB
     # then it will have an empty list
     # and we can return False
     if not occurences[e]:
         return False

     # now the next possible index for the next character in listA
     # must be *greater* than the index of the last character we found
     # if no such index exists, then listA is not contained within listB
     # if it is, we update the last seen index
     next_possible_index = [x for x in occurences[e] if x > last_index]
     if not next_possible_index:
         return False
     last_index = next_possible_index[0]

   # if we make it out of the for loop
   # then all is well, and listA is contained in listB
   # but not necessarily consequtively 
   return True

答案 1 :(得分:0)

def f(l1, l2):
    i1 = 0
    i2 = 0

    while i1 < len(l1) and i2 < len(l2):
        if l1[i1] == l2[i2]:
            i1 += 1
            i2 += 1
        else:
            i2 += 1

    if i1 == len(l1):
        return True
    return False

listA = [1, 2, 3, 66, 0]
listB = [0, 0, 1, 2, 3, 66, 0, 99, 0, 3]

print (f(listA, listB))
# will print true