2016-03-15 50 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