比较另一个列表中的所有项目以及相同的顺序

时间:2017-03-04 03:51:16

标签: python

在下面的代码中,如何仅将这些值返回为True,其中在routelist中遵循checklist中的元素顺序?

例如: checklist(["BOMH","DELH","BRGH"])应该返回True ["BOMH","CCUH","DELH","BRGH"]而不是["BOMH","BRGH","CCUH","DELH"]

def checklhcost2(checklist):
    thcdataselect["shortlist"] = thcdataselect.apply(lambda x:\
                True if all((i in x["routelist"] for i in checklist)) else False)
    return thcdataselect.filter_by(1,"shortlist")

4 个答案:

答案 0 :(得分:2)

使用映射确定每个值的权重,过滤掉不匹配的值,并检查它是否正确排序:

master = ["BOMH","DELH","BRGH"]
ordering = {item:idx for idx,item in enumerate(master)}
check1 = ["BOMH","CCUH","DELH","BRGH"]
check2 = ["BOMH","BRGH","CCUH","DELH"]

def check(o, c):
    return all(o[i]==r for i,r in zip((i for i in c if i in o), range(len(o))))

结果:

>>> check(ordering, check1)
True
>>> check(ordering, check2)
False

答案 1 :(得分:1)

>>> chk = ["BOMH","DELH","BRGH"]
>>> one = ["BOMH","CCUH","DELH","BRGH"]
>>> two = ["BOMH","BRGH","CCUH","DELH"]

为会员资格测试制作一套

>>> set_chk = set(chk)

用于过滤和维护订单的生成器表达式

>>> one_a = (thing for thing in one if thing in set_chk)
>>> two_a = (thing for thing in two if thing in set_chk)

使用zip配对chk中的项目和目标列表进行比较。

>>> all(a == b for a, b in zip(chk, one_a))
True
>>> all(a == b for a, b in zip(chk, two_a))
False

要确保所有项目都存在且顺序正确,请使用itertools.zip_longest

>>> three = ['BOMH', 'CCUH', 'DELH']
>>> three_a = (thing for thing in three if thing in set_chk)
>>> 
>>> from itertools import zip_longest
>>> 
>>> all(a == b for a,b in zip_longest(chk, three_a))
False
>>> 

使用zip会产生错误的结果:

>>> all(a == b for a,b in zip(chk, three_a))
True

或者只是制作新的,已过滤的列表并进行比较。

>>> one_a = [thing for thing in one if thing in set_chk]
>>> two_a = [thing for thing in two if thing in set_chk]
>>> three_a = [thing for thing in three if thing in set_chk]

>>> one_a == chk
True
>>> two_a == chk
False
>>> three_a == chk
False

答案 2 :(得分:1)

def checklhcost2(values):
    expected_seq = ["BOMH","DELH","BRGH"]
    # for each element in expected_seq get index from values
    L = [values.index(v) if v in values else -1 for v in expected_seq]
    # if indexes are in increasing order and >1 then return True
    return all(x<y and x > -1 for x, y in zip(L, L[1:]))

checklhcost2(["BOMH","CCUH","DELH","BRGH"])
#True
checklhcost2(["BOMH","BRGH","CCUH","DELH"])
#False

它也可用于边缘情况,其中expected_seq具有输入参数不是示例的值

expected_seq = ["BOMH","DELH","BRGH", "other"]

checklhcost2(["BOMH","CCUH","DELH","BRGH"])
#False
checklhcost2(["BOMH","BRGH","CCUH","DELH"])
#False

答案 3 :(得分:0)

不确定这是一个很好的解决方案,但它似乎有效。

>>> checklhcost2 = lambda chl: reduce(lambda x,y: x and routelist.index(y[1]) == y[0], enumerate([ itm for itm in chl if itm in routelist]), True )
>>> checklhcost2(["BOMH","CCUH","DELH","BRGH"])
True
>>> checklhcost2(["BOMH","BRGH","CCUH","DELH"])
False
>>> 

主要思想很简单:过滤掉不在routelist中的所有内容,然后枚举其余内容并检查索引。返回所有索引的逻辑和匹配(reduce函数)。