2017-06-16 30 views
1

我正在使用python,而且我基本上有一個包含不同元素的列表。如果我打印一些元素,它看起來像下面這樣:如何檢查兩個列表中的元素是否相同(順序已更改)

print('%s'%list[0]) 
print('%s'%list[1]) 

Output: 
[('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')] 
[('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')] 

我想檢查一個元素是否在這兩個列表中重複。但它可以以不同的順序重複。例如,元素('A','B')重複,但在第二個列表中的順序不同('B','A')。

我想比較列表[0] [0](即('A','B'))與列表[1]的所有元素並獲得元素列表[0] [2] 。

我該怎麼做?

謝謝

+0

如果在同一個列表中重複該怎麼辦?是否計數或是錯誤? –

回答

0

您可以使用set.intersection方法返回來自兩個(或更多)集合的任何共享元素。在下面的例子中,每個元組列表首先被轉換爲一組集合。請注意,每個元組映射到一個frozenset,因此它仍然是可散列的。該函數然後返回任何共享項目的列表。爲了與原始輸入對象類型保持一致,返回列表中的每個項目都會轉換回元組。

def listSharedItems(list1, list2): 
    list1_sets = set(map(frozenset,list1)) 
    list2_sets = set(map(frozenset,list2)) 
    intersect = list1_sets.intersection(list2_sets) 
    return map(tuple,intersect) 

>>> # Example usage: 
>>> alist = [[('A','B'), ('D','E'), ('B','Z'), ('Z','D')], 
      [('B','M'), ('M','R'), ('B','A'), ('R','Z'), ('H','M')]] 
>>> listSharedItems(alist[0], alist[1]) 
>>> [('A', 'B')] 
2

你可以把你的元組變成集;這樣的順序並不重要:

a = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')] 
b = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')] 

a_set = list(set(item) for item in a) 
b_set = list(set(item) for item in b) 

# create a list of items that are in a and b: 
res = [item for item in a_set if item in b_set] 
print(res) # [{'A', 'B'}] 

如果速度是一個問題,你甚至可以這樣:

a_set = set(frozenset(item) for item in a) 
b_set = set(frozenset(item) for item in b) 

res = a_set & b_set 
# {frozenset({'A', 'B'})} 

這可能然後很容易地轉換回含元組res = [tuple(item) for item in res]列表。

請注意,重複項將被視爲最後一個版本中的單個項目。

+1

或甚至:'在a中設置(frozenset(item)爲item中的項目).intersection(frozenset(item)爲b中的項目)'那麼你不需要同時設置這兩個套件 –

+0

@JonClements很好!沒想到那個! –

0

您可以使用兩個for循環,以獲得真正的,如果元素匹配,將它們轉換爲臺(套,因爲沒有一個順序):

l1 = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')] 
l2 = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')] 

elementToCompare = set(l1[0]) 

for i in l2: 
    if elementToCompare == set(i): 
     print("%s is the same as %s"%(l1[0], i)) 

輸出:

('A', 'B') is the same as ('B', 'A') 
+0

這比算法複雜得多,因爲它需要...因爲嵌套循環,你會比較你已經完成的事情... –

+0

@JonClements這是真的,但再次閱讀他的要求:**我想比較列表[0] [0](即('A','B'))與列表[1]的所有元素相同,並獲得元素列表[0] [2]的真。**這正是他想要做的 – moritzg

+0

如果你嚴格遵循這個規則,那麼就沒有必要循環使用'l1'了? –

1

如果元素可以多次包含某些項目,並且set因此不起作用,您還可以使用sorted來規範元素內的順序。

>>> a = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')] 
>>> b = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')] 
>>> b_set = set([tuple(sorted(x)) for x in b]) 
>>> [x for x in [tuple(sorted(y)) for y in a] if x in b_set] 
[('A', 'B')] 

請注意,如果你想使用一個set使查找更快,你必須包裹sorted元素融入tuples所以他們是哈希的。

相關問題