2013-04-01 115 views
1

我有一個列表列表;每個列表都有規定的第一個和最後一個值。對於每個第一個和最後一個值組合,我希望找到唯一列表的總數。唯一性的定義是,列表中間(第一個值和最後一個值之間)的元素之間不能有重複的元素,這些元素具有相同的第一個和最後一個值組合。列表中第一個和最後一個值被修復的列表中的唯一列表Python

例如,對於以下列表的列表;

[[2, 5, 7, 12], [2, 5, 10, 12], [2, 3, 12], [3, 34, 4, 6], [3, 4, 6]] 

有2個第一個和最後一個值組合:[2,...,12]和[3,...,6]。 一組獨特的名單將是:

[[2, 5, 7, 12], [2, 3, 12], [3, 34, 4, 6]] 

獨特列出的其他組合是可能的,但我只關心與獨特列表的數量。對於上面的示例,組合[2,...,12]有2個唯一列表,組合[3,...,6]有1個唯一列表。

什麼是在Python中做到這一點的最佳方式?

回答

2

最直接的方法是索引所有列表的第一個和最後一個值,然後過濾這些列表。

你可以通過將所有這些列表添加到字典中,所有的鍵都是(first, last)元組。然後,您會查看其中的每一個並刪除重複項。

一個簡單的例子:

mapping = defaultdict(list) 
for item in target_lists: 
    mapping[item[0], item[-1]].append(item) 

for k, items in mapping.iteritems(): 
    mapping[k] = [some_filter_function(v) for v in items] 

您必須修改這個位來設置你的病情來決定,如果它是一個重複的或不(我不知道我理解你的標準)。

希望它有幫助!

更新

我想我明白你的標準。你必須做的是記錄列表中的哪些元素不止一次出現。然後你瀏覽列表,根據你製作的記錄(只記錄一次)檢查是否存在不應該存在的元素。如果有,則丟棄該元素。一種做法與此類似:

for k, items in mapping.iteritems(): 
    count_item = defaultdict(int) 
    for item in items: 
     for i in item[1:-1]: 
      count_item[i] += 1 
    mapping[k] = [item for item in items if all(count_item[i] == 1 for i in item[1:-1])] 

這是實現它的方法之一。但我幾乎可以肯定,你將不得不做2個循環:一個檢查哪些是要拒絕的元素,一個是做實際的過濾。實施可能會有所不同。

+0

的建議非常感謝,字典效果很好。儘管如此,我仍然在爲filter_function而努力。我的標準如下:一個唯一列表(對於給定的第一個和最後一個組合)是在任何其他列表(第一個和最後一個組合)中都沒有找到任何中間元素(在第一個和最後一個元素之間)的列表。我希望那更清楚。 –

+0

@scott_ouce我更新了我的答案。它的方式(在一個單獨的函數中),您將不得不將它傳遞給您正在處理的列表,並且效率會降低,因爲您需要*每次*檢查所有其他項目,而不是執行一次。我希望我有道理:) – jadkik94

1

這個怎麼樣,使用defaultdict跟蹤頭部+尾部標識,並設置相符的唯一條目:

from collections import defaultdict 

a = [[2, 5, 7, 12], [2, 5, 10, 12], [2, 3, 12], [3, 34, 4, 6], [3, 4, 6]] 
dic = defaultdict(lambda: set()) 
for item in a: 
    dic[(item[0], item[-1])].add(tuple(item[1:-1])) 

for id, variants in dic.items(): 
    print "ID %s: %i unique entries" % (str(id), len(variants)) 
+0

非常感謝您的建議。該字典可以很好地管理head + tail,但是我選擇「unique」列表的標準不是使用簡單的集合來處理的。相反,我的標準如下:一個唯一的列表(對於給定的頭部+尾部組合)是在任何其他列表中找不到任何中間元素(頭部+尾部ID之間)的頭部+尾部組合)。我希望那更清楚 –

相關問題