簡體   English   中英

遞歸檢查值是否在字典列表中

[英]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,10,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)表示ab連接。 這意味着這兩個節點應該共享相同的節點集,因為它們(通過彼此)連接到所有鄰居的並集。

我們假設節點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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM