2017-05-29 48 views
0

一個元件我需要組子列表具有相同的元件一起並在子列表的所有元素都沒有元件在list2list3 例如有一個元件:的Python鏈路子列表一起子列表具有在list2中沒有元件,並具有在項目list3

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[13,15]] 
list2 = [7,8] 
list3 = [1,6,11,13] 

我將連接[4,5][1,4]在一起,因爲它們都包含1個相同數量和這兩個會結合成[1,4,5]和它們所包含1list3和不含7list2

因此,鏈接後,新的名單應該是這樣的:

new_list1 = [[1,4,5],[6],[11],[13,15]] 

IE:不應該有一個子列表內相同數量和順序並不重要。

較長的例子:

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]] 
list2 = [7,8,20] 
list3 = [1,2,3,16,15] 

鏈接後,這將是

new_list = [[1,4,5],[2,3],[11,14,16],[13,15]] 

這怎麼能在一般的方式進行?

編輯 最終的算法應包括以下三個基本步驟:

  1. 刪除包含在list2
  2. list1所有子列表中的所有元素加入的所有子列表list1有共同元素
  3. 刪除所有子列表list1不包含任何元素list3
+3

這是我不太清楚列出你爲了得到期望的結果是聯繫。在你的第一個例子中,'[1,4]'從哪裏來? –

+0

對不起,我修正了它,在列表中1 – jack

+0

你有沒有嘗試過任何東西? – Nuageux

回答

2

以下是一張就可以了,如果托馬斯·庫恩設法正確瞭解你的心思:

def subgroup_join(data, exclude, include): 
    exclude = set(exclude) # turn into set for faster lookup/compare 
    include = set(include) # turn into set for faster lookup/compare 
    data = [set(element) - exclude for element in data] # remove excluded elements 
    results = [set()] # init with an empty set 
    for element in data: # loop through our remaining elements 
     groups = [] # store elements/current results filtered by exclude list 
     ignore_element = False # flag if we should add the element as a standalone 
     for result in results: # go through each subgroup in the results 
      if element & result: # if the current element has common items with the result 
       result |= element # ... concatenate both into a subgroup 
       ignore_element = True 
      groups.append(result) # add the current result subgroup 
     if not ignore_element: # add only if the element wasn't concatenated 
      groups.append(element) # add the current element 
     results = groups # our element store becomes our new results set 
    return sorted([sorted(res) for res in results if result & include]) # sort & return 

至於測試:

list1 = [[1, 4], [4, 5], [5, 7], [6, 7], [7, 8], [9, 7], [10, 9], [8, 10], [8, 11], [8, 13], [13, 15]] 
list2 = [7, 8] 
list3 = [1, 6, 11, 13] 

print(subgroup_join(list1, list2, list3)) 
# prints: [[1, 4, 5], [6], [11], [13, 15]] 

list1 = [[1, 4], [4, 5], [5, 7], [6, 7], [9, 7], [10, 9], [8, 10], [8, 11], [8, 13], [6, 8], [20, 2], [20, 3], [11, 14], [14, 16], [13, 15]] 
list2 = [7, 8, 20] 
list3 = [1, 2, 3, 16, 15] 

print(subgroup_join(list1, list2, list3)) 
# prints: [[1, 4, 5], [2], [3], [11, 14, 16], [13, 15]] 

這可能是從呈現最快的方法,但同樣 - 它與您的示例不完全匹配 - 請檢查最後的結果集和[2][3]結果。

UPDATE

當涉及到性能,使用第二個列表組:

zwer_join - 100,000 loops: 2.849 s; per loop: 28.399 µs 
kuhn_join - 100,000 loops: 3.071 s; per loop: 30.706 µs 
nuag_join - 1,000 loops: 15.82 s; per loop: 15.819 ms (had to reduce the number of loops) 
+0

結構非常好。你肯定有更多的練習套裝比我做:) –

0

首先,你首先編寫你的join函數。我列入第二個列表以刪除不需要的元素。

然後您遍歷您的聯接列表,並查看是否有任何元素當前在您的列表中。如果是的話,你尋找他們所屬的地方,然後添加元素(我使用set以避免重複)。

輸出在最後給出。

def join(list1, list2): 
    l = [] 
    for ee in list1: 
     # We consider here that list1 only have pairs 
     if ee[0] not in list2 and ee[1] not in list2: 
      flat_l = [x for e in l for x in e] 
      if ee[0] in flat_l or ee[1] in flat_l: 
       for i, e in enumerate(l): 
        if ee[0] in e: 
         l[i].append(ee[1]) 
        if ee[1] in e: 
         l[i].append(ee[0]) 
      else: 
       l.append(ee) 
    return l 

def f(list1,list2,list3): 
    l = [[e] for e in list3] 
    list1 = join(list1, list2) 
    for ee in list1: 
     flat_l = [x for e in l for x in e] 
     for e in ee: 
      if e in flat_l: 
       for i in range(len(l)): 
        if e in l[i]: 
         l[i] = list(set(l[i]+ee)) 
    print(l) 

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[13,15]] 
list2 = [7,8] 
list3 = [1,6,11,13] 

f(list1,list2,list3) 
# [[1, 4, 5], [6], [11], [13, 15]] 

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]] 
list2 = [7,8,20] 
list3 = [1,2,3,16,15] 

f(list1,list2,list3) 
# [[1, 4, 5], [2], [3], [16, 11, 14], [13, 15]] 
+0

是否有可能使其更快? – jack

+0

可能取決於你準備做的努力和時間。你仍然依賴於'append()',這很慢。 – Nuageux

1

此代碼應該做的工作:

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]] 
list2 = [7,8,20] 
list3 = [1,2,3,16,15] 

list1a = [set(l) for l in list1] 
#removing elements from list1 that contain numbers of list2: 
for x in list2: 
    for l in list(list1a): 
     if x in l: 
      l.remove(x) 

#joining sub-lists in list1: 
list1b = [set(l) for l in list1a] 
list1c = [] 
while list1b: 
    s1 = list1b.pop(0) 
    for s2 in list(list1b): 
     if s1 & s2: 
      s1 |= s2 
      list1b.remove(s2) 
    list1c.append(s1) 

#generating final list with only sub-lists that contain elements of list2 
list1_new = sorted([sorted(list(s)) for s in list1c if s & set(list3)]) 

第一個例子,這給:

[[1, 4, 5], [6], [11], [13, 15]] 

,並在第二個例子中

[[1, 4, 5], [2], [3], [11, 14, 16], [13, 15]] 

希望這幫助。

+0

第二個結果集並不像OP在他的例子中顯示的那樣產生一個單獨的[2,3]。 – zwer

+0

@zwer我知道。它不能工作,因爲'20'在'禁止列表'中,因此'[20,2]'和'[20,3]'不能連接。提問者一定是錯誤的。 –

+0

我知道這一點,我知道它爲什麼不會產生正確結果的原因,但是要麼是算法更重要,要麼是問題中存在錯誤,並且此時不能確定考慮到說明OP有能力解釋他的問題。 – zwer

相關問題