2016-03-15 39 views
0

我一直在尝试在Python 2.7中使用两个列表。我已经走了一段路,但花时间搜寻并没有带来太多的结果。与Python的逆向匹配

List1:是我在List2中搜索的特定数字序列的列表。 (例如)['209583', '185372', '684392', '995423']

List2:在list1中有这些数字的变化。 (例如)['209583_345829', '57185372', '853921864']

现在我可以匹配和拉下我在下面找到的东西......但我也在寻找反过来;将一个变量设置为List1中不在List2中的所有数字。

matching = [s for s in list2 if any(xs in s for xs in list1)] 

那么应该留在一个不匹配的变量应该是'995423'。我已经尝试过重新编写上面的代码,但我觉得它正好在我的鼻子下面。

此外,出于性能原因使用If/Else语句会不会有好处?例如。如果匹配做到这一点,否则不匹配做到这一点......这种方式只能运行一次,而不是两次。

这是一个简单的例子,但是两者的列表可能会超过10,000行。

谢谢!书面

+0

所以...只是扭转的条件,我猜? 'non_matching = [s for s in list1 if any any(xs in s for xs in list2)]'(< - if ** not ** any) – yedpodtrzitko

+0

我已经试过了。这将从list1返回那些没有从list2引用的列表。我正在寻找那些list1中没有任何引用的列表1。 – sdavis891

+0

由于事实上1中的数字序列可以位于2的数字中的任何一个事实,所以这相反更为复杂。问题:列表1中的数字是否可靠地保留六位数字? – BHustus

回答

0

第一件事第一件事:你手边的列表理解是错误的。为了完成一个完整的List1中有匹配在列表2项目列表,你想用这样的:在列表2

所有项目从列表1火柴
matches = [item for item in List1 if any(item in compared for compared in List2)] 

为了解释:
[s for s in List1 if any(xs in s for xs in List2)] - 您的原始算法正在从List1提取元素s,从List2提取元素xs,并试图查看xs是否包含在s中,这本质上与我们想要做的相反。

[s for s in list2 if any(xs in s for xs in list1)] - 您的新算法颠倒了错误的变量。现在它从List2xs拉从List1并检查xs是否在s - 这更接近于最初的想法。唯一的问题是,你的算法设置方式,它将把从List2项目到列表中,如果他们在List1比赛

[item for item in List1 if any(item in compared for compared in List2)](其中可能是你想要的毕竟是什么?) - 制造为了便于阅读,稍微详细一点,该算法将从List1中提取项目,检查它们是否在List2中有一个“容器”,如果他们有,则将它们添加到列表中。 (附注:替代列表理解,将返回相同的结果是[item for item in List1 for compared in List2 if item in compared],这是一个比较直观的阅读。)

有了这样的方式:如果你想从列表1得到每个项目没有匹配列表2,你可以使用我上面指定的算法来获得matches列表中,然后,作为阿里说,奥马尔在评论指出,使用集合操作:

所有项目IN List1没有List2中的匹配 - 设置操作

nomatches = set(List1) - set(matches) 

这将采取所有独特元素List1,删除匹配的元素,并与所有的联合国匹配元件的剩余返回set对象。另外,如果你想在一个声明中的解决方案:

所有项目List1中没有火柴在列表2 - 列表理解

nomatches = [item for item in List1 if not any(item in compared for compared in List2)] 

要给予信贷,信贷是因为,这等同于在后yedpodtrzitko的解决方案注释。

因为它是很难告诉你在问什么,不过,在评论你有倒装以失败告终你问至少有一次是什么,我会再增加两个算法:

全部项目列表2 WITH列表综合

nomatches2 = [item for item in List2 if not any(key in item for key in List1)] 

全部项目列表2而不列表1场比赛 - - 设置操作列表1

matches2 = [item for item in List2 for key in List1 if key in item] 

全部项目列表2而不列表1场比赛的比赛

nomatches2 = set(List2) - set(matches2) 

这些都已通过您的帖子中描述的测试用例进行过测试,并返回了预期结果。如果这些算法不能满足您的需求,请仔细检查一下,这不是您的问题,如果这不能解决您的问题,请确保您清楚所询问的内容。谢谢。

+0

通过解释所有不同的场景,我能够混合搭配您发布的内容,以便做我想做的事。我原来的代码做了它想象的。然而,我发布的名单在我使用的名单中却发生了逆转。因此,从这个例子发布:匹配= [s为列表2中的s如果有的话(xs in s for xs in list1)]我正在寻找list1中与list2匹配的ALL。然后我用这个从list1中找到所有与我原始结果不匹配的东西。 notmatching = [c对于list1中的c,如果没有的话(c中xc中的xc匹配)]我希望这是有道理的! – sdavis891

+0

我仍然不完全确定我得到了您想要的东西列表,但我很高兴能够让您找到您的解决方案。 :) – BHustus

+0

相信我,我迷惑自己哈哈。 Python对我来说仍然是新的,我似乎学习的唯一方法就是通过做。非常感谢! – sdavis891

0

你“匹配”从list2给人的值,而不是从list1['209583_345829', '57185372']

这就是为什么所描述的“设置”的做法没有奏效。您需要重写匹配,以便它返回list1中具有list2中相应值的项目。

鉴于你的问题的描述,这应该工作:

non_match = [xs for xs in list1 if not any (xs in s for s in list2)] 

然而,返回['684392', '995423']。我在任何地方都看不到684392list2;你有没有在某个时间点编辑列表,或者你是否在列表2中查找包含列表1中所有项目的数字而不仅仅是项目本身的内容?

+0

感谢您的答案@A。 Leistra Bhustus设法帮助我。这正是我用不同的标识符进行的。不匹配= [c对于list2中的c,如果不是任何(匹配xc中的c,xc)]。 *我的列表与我的最终结果不同,这就是List1-2切换的原因。 – sdavis891