2016-11-26 28 views
1

使用3.x版本 - 想知道解决以下最简单的和原生的方式:删除差,但维持秩序和重复在Python列表

列表示例:

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的大脑测试:

请编写打印“YES”,如果B的元素在他们出现的顺序发生在一个程序B但不一定是连续的。否则,程序应打印“否”。

Linday的奖金测试:

请编写打印“YES”,如果B的元素在 顺序发生在它们出现在B和连续的程序。

很明显,如果任何人都幻想挑战,那么请发布完整的程序来解决这2个问题。

+0

Linday的大脑测试只是询问B是否是A的**子序列**,对吗? –

+1

你写道:*“列表B永远不会有重复的数字,不像列表中的whist [sec]可能有重复。”*:但是您提供的示例违反了这个条件:* listB *在您的示例中有重复。 – trincot

+0

我已经纠正了这个错误,但Trincot你的解决方案为第一部分工作,非常感谢你的布局和简单。你可以重新发布奖励问题解决方案 – NoobyD

回答

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在评论中指出了这个问题。

闻听此事打印“YES”和“NO”是非常简单的:

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

失败,例如'aInB([1],[11])'。 –

+0

好的。虽然有一个解决方案。 – TheF1rstPancake

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 
+0

好吧,你显然是一个聪明的家伙 - 我如何在不创建这个功能的情况下在同一个程序中实际使用它? – NoobyD

+0

对不起,这只是一个想法来解决问题,应打印'是'或'否' – Gnukos

+0

为什么你不想创建一个函数? – Gnukos