[英]Recursively checking if value is in dictionary list
我有以下格式的數據:
lsta = [[0,1], [0,2], [1,3], [2,4], [3,5], [4,6], [5,7], [7,9], [8,10], [8,11], [10,12], [11,13], [11,14], [12,15], [12,16], [6,17], [8,17]]
我正在嘗試根據是否已連接將數據分為兩個列表,因此我想您可以將數據視為圖形。 目前,我有一個遞歸函數,它將按照[0,1]
-> [1,3]
-> [3,5]
等順序跟蹤數據。
但是,當編號順序不正確時,這種情況會惡化; 例如,連接了6、17和8,但是由於原始數據的格式,這將被分成多個列表。 我對此的預期解決方案是在用完以下序列后執行檢查,以查看是否在字典中的其他位置(不僅是鍵)找到了該值,如果這樣,該函數將繼續從該點開始。 不幸的是,我無法完全正常運行,建議表示贊賞。
在下面的當前代碼中,“檢查”功能當前未按預期執行。
from collections import defaultdict
def split(items):
# create lookup
lookup = defaultdict(set)
for k, v in items:
lookup[k].add(v)
results = []
while sum(map(len, lookup.values())):
# get first element from remaining items
first_k = min((k for k in lookup if len(lookup[k])))
first = first_k, min(lookup[first_k])
# follow that element
results.append(follow(first, lookup))
return results
def follow(item, lookup):
item_k, item_v = item
lookup[item_k].remove(item_v)
result = [item]
# loop through all follow-up items (if any)
for next_item in sorted(lookup[item_v]):
# recursively follow the follow-up item
result.extend(follow((item_v, next_item), lookup))
try:
#check if v appears in v of another key
result.extend(check((item_v, next_item), lookup))
except KeyError:
break
return result
def check(item, lookup):
itm_k, itm_v = item
rsult = []
if itm_v in lookup.values():
#if it appears again, follow item
rsult.extend(follow((itm_k, next_item), lookup))
return rsult
def test(items):
for x in split(items):
print(x)
lsta = [
[ 0, 1], [ 0, 2], [ 1, 3], [ 2, 4],
[ 3, 5], [ 4, 6], [ 5, 7], [ 7, 9],
[ 8, 10], [ 8, 11], [10, 12], [11, 13],
[11, 14], [12, 15], [12, 16], [ 6, 17],
[ 8, 17],
]
test(lsta)
所需的輸出為:
results = ([[0,1], [1,3], [3,5], [5,7], [7,9]], [[0,2], [2,4], [4,6], [6,17], [8,17], [8,10], [8,11], [11,13], [11,14], [10,12], [12,15], [12,16]])
我建議您退后一步,以另一種方式考慮問題。 根據您的問題,您正在嘗試標識lsta
對列表中的連接子圖。 根據你的圖表簡單地連接 -即(A,B)是沒有意義的指向性的相同(B,A)。
查看前兩對,您有0,1
和0,2
。 這會產生一個由{0,1,2}
組成的子圖,因為您實際上並不在意哪一端是公共的。 set
類型將是您解決方案的關鍵。 不必擔心遞歸,請嘗試管理集合以獲得所需的結果。
首先,導入集合,然后設置默認字典。 您不需要直接導入defaultdict,因為您只需要鍵入一次即可,這將使您的工作變得簡單:
import collections
Subgraphs = collections.defaultdict(set)
現在,讓我們添加您的初始測試數據。 請注意:這里有一個“ bug”,因為最后一對(8,17)將子圖連接在一起。 您可能不想要那樣。
lsta = [
[ 0, 1], [ 0, 2], [ 1, 3], [ 2, 4],
[ 3, 5], [ 4, 6], [ 5, 7], [ 7, 9],
[ 8, 10], [ 8, 11], [10, 12], [11, 13],
[11, 14], [12, 15], [12, 16], [ 6, 17],
[ 8, 17],
]
現在讓我們初始化集合。 每個節點 (整數)將指向它連接到的集合。 最初,節點僅相互連接,因此每個密鑰K
都將指向集合{K}
。
for a,b in lsta:
Subgraphs[a].add(a)
Subgraphs[b].add(b)
現在,讓我們合並集合。 每對(a,b)
表示a
和b
連接。 這意味着這兩個節點應該共享相同的節點集,因為它們(通過彼此)連接到所有鄰居的並集。
我們假設節點A指向一個集合,並且該集合中的所有節點也都指向同一集合。 (這是一些Python的詭計。它們不是同一集合的副本 ,而是對內存中相同對象的實際引用 。)這意味着更新該集合只能執行一次,並且將影響所有成員。 。
for a,b in lsta:
seta = Subgraphs[a]
setb = Subgraphs[b]
others = setb - seta
seta |= setb
print("Processing (%d, %d): %s" % (a, b, seta))
print("... updating: ", others)
for o in others:
Subgraphs[o] = seta
此時,“ Subgraphs
字典中的所有鍵(節點)都應指向包含其所有可及鄰居的集合。 我們將打印輸入和結果數據,然后交給您。
print("\n***********")
print(lsta)
print(Subgraphs)
您可能要刪除最后一對:[8,17]。 另外,您可能希望標識唯一的子圖。 我不知道您在用這段代碼做什么,但是如果您確實需要這些子圖,則可以將它們設置為frozenset
對象,然后可以將其添加到set
以生成不同的集合。 或者,您可以僅迭代Subgraphs
dict的鍵,將集合合並為seen
集合,並跳過已經seen
任何鍵。
這是我按lsta
運行lsta
數據時得到的輸出:
Processing (0, 1): {0, 1}
... updating: {1}
Processing (0, 2): {0, 1, 2}
... updating: {2}
Processing (1, 3): {0, 1, 2, 3}
... updating: {3}
Processing (2, 4): {0, 1, 2, 3, 4}
... updating: {4}
Processing (3, 5): {0, 1, 2, 3, 4, 5}
... updating: {5}
Processing (4, 6): {0, 1, 2, 3, 4, 5, 6}
... updating: {6}
Processing (5, 7): {0, 1, 2, 3, 4, 5, 6, 7}
... updating: {7}
Processing (7, 9): {0, 1, 2, 3, 4, 5, 6, 7, 9}
... updating: {9}
Processing (8, 10): {8, 10}
... updating: {10}
Processing (8, 11): {8, 10, 11}
... updating: {11}
Processing (10, 12): {8, 10, 11, 12}
... updating: {12}
Processing (11, 13): {8, 10, 11, 12, 13}
... updating: {13}
Processing (11, 14): {8, 10, 11, 12, 13, 14}
... updating: {14}
Processing (12, 15): {8, 10, 11, 12, 13, 14, 15}
... updating: {15}
Processing (12, 16): {16, 8, 10, 11, 12, 13, 14, 15}
... updating: {16}
Processing (6, 17): {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}
... updating: {17}
Processing (8, 17): {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}
... updating: {0, 1, 2, 3, 4, 5, 6, 7, 9, 17}
*********
LSTA: [[0, 1], [0, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7], [7, 9], [8, 10], [8, 11], [10, 12], [11, 13], [11, 14], [12, 15], [12, 16], [6, 17], [8, 17]]
Subgraphs: defaultdict(<class 'set'>, {0: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 1: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 2: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 3: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 4: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 5: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 6: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 7: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 8: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 9: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 10: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 11: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 12: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 13: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 14: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 15: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 16: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, 17: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}})
這是從lsta
刪除[8,17]對時的lsta
:
Processing (0, 1): {0, 1}
... updating: {1}
Processing (0, 2): {0, 1, 2}
... updating: {2}
Processing (1, 3): {0, 1, 2, 3}
... updating: {3}
Processing (2, 4): {0, 1, 2, 3, 4}
... updating: {4}
Processing (3, 5): {0, 1, 2, 3, 4, 5}
... updating: {5}
Processing (4, 6): {0, 1, 2, 3, 4, 5, 6}
... updating: {6}
Processing (5, 7): {0, 1, 2, 3, 4, 5, 6, 7}
... updating: {7}
Processing (7, 9): {0, 1, 2, 3, 4, 5, 6, 7, 9}
... updating: {9}
Processing (8, 10): {8, 10}
... updating: {10}
Processing (8, 11): {8, 10, 11}
... updating: {11}
Processing (10, 12): {8, 10, 11, 12}
... updating: {12}
Processing (11, 13): {8, 10, 11, 12, 13}
... updating: {13}
Processing (11, 14): {8, 10, 11, 12, 13, 14}
... updating: {14}
Processing (12, 15): {8, 10, 11, 12, 13, 14, 15}
... updating: {15}
Processing (12, 16): {16, 8, 10, 11, 12, 13, 14, 15}
... updating: {16}
Processing (6, 17): {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}
... updating: {17}
*********
LSTA: [[0, 1], [0, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7], [7, 9], [8, 10], [8, 11], [10, 12], [11, 13], [11, 14], [12, 15], [12, 16], [6, 17]]
Subgraphs: defaultdict(<class 'set'>, {0: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 1: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 2: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 3: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 4: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 5: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 6: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 7: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 8: {16, 8, 10, 11, 12, 13, 14, 15}, 9: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}, 10: {16, 8, 10, 11, 12, 13, 14, 15}, 11: {16, 8, 10, 11, 12, 13, 14, 15}, 12: {16, 8, 10, 11, 12, 13, 14, 15}, 13: {16, 8, 10, 11, 12, 13, 14, 15}, 14: {16, 8, 10, 11, 12, 13, 14, 15}, 15: {16, 8, 10, 11, 12, 13, 14, 15}, 16: {16, 8, 10, 11, 12, 13, 14, 15}, 17: {0, 1, 2, 3, 4, 5, 6, 7, 17, 9}})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.