Periksa keberadaan kunci secara rekursif dan tambahkan ke array dict

Saya punya dikt sebagai berikut

{
   "key1" : "value1",
   "key2" : "value2",
   "key3" : "value3",
   "key4" : {
       "key5" : "value5"
   }
}

Jika dict tersebut memiliki key1==value1, saya akan menambahkan dict tersebut ke dalam daftar.

Misalkan key1==value1 tidak ada pada pasangan nilai kunci pertama, padahal key1==value1 berada di dalam dict bersarang sebagai berikut:

{
   "key2" : "value2",
   "key3" : "value3",
   "key4" : {
       "key5" : "value5",
       "key1" : "value1",
       "key6" : { 
          "key7" : "value7",
          "key1" : "value1"
       }
   },
   "key8" : { 
       "key9" : "value9",
       "key10" : {
            "key11" : "value11",
            "key12" : "value12",
            "key1" : "value1"
       }
   }
}

Pada dict di atas saya harus cek dulu apakah ada key1=value1. Jika tidak, saya harus melintasi dict yang disarangkan dan jika ditemukan di dict yang disarangkan, saya harus menambahkan dict itu ke daftar. Jika dict yang disarangkan juga merupakan dict yang disarangkan tetapi key1=value1 ditemukan di pasangan nilai kunci pertama, maka tidak perlu memeriksa dict bagian dalam (Misalnya, key4 memiliki key1=value1 di pasangan nilai kunci pertama. Oleh karena itu, tidak perlu periksa bagian dalam meskipun key6 memiliki key1=value1).

Jadi akhirnya, saya akan memiliki daftarnya sebagai berikut.

[
   {
       "key5" : "value5",
       "key1" : "value1",
       "key6" : { 
          "key7" : "value7",
          "key1" : "value1"
       }
   },
   {
            "key11" : "value11",
            "key12" : "value12",
            "key1" : "value1"
   }
]

Bagaimana cara mencapainya? Catatan: Kedalaman dict mungkin berbeda-beda


person NagaLakshmi    schedule 27.03.2015    source sumber
comment
Apakah Anda memiliki perintah mendalam yang sewenang-wenang atau hanya sampai batas yang dapat dikelola?   -  person syntonym    schedule 27.03.2015
comment
@syntonym Dengan asumsi itu sewenang-wenang dalam..   -  person NagaLakshmi    schedule 27.03.2015


Jawaban (1)


jika dict berisi key1 dan value1 kami akan menambahkannya ke daftar dan menyelesaikannya. jika tidak, kita akan memasukkan semua nilai di dict yaitu dict dan melakukan logika yang sama juga

l = []
def append_dict(d):
    if d.get("key1") == "value1":
        l.append(d)
        return

    for k,v in d.items():
        if isinstance(v, dict):
            append_dict(v) 


append_dict(d)
print l

solusi berulang akan menambahkan ke antrian dict yang ingin kami periksa:

from Queue import Queue
q = Queue() 
l = []
q.put(d)
while not q.empty():
    d = q.get()
    if d.get("key1") == "value1":
        l.append(d)
        continue
    for k,v in d.items():
        if isinstance(v, dict):
            q.put(v) 

print l

Seperti yang dicatat oleh @shashank, menggunakan stack alih-alih queue juga akan berfungsi. Ini adalah BFS vs DFS untuk mencari di kamus

person Udy    schedule 27.03.2015
comment
Bukankah if d[k] == v cukup? Juga bersifat rekursif yang mungkin tidak berfungsi untuk dicts dalam yang sewenang-wenang (karena kedalaman rekursi python max) tetapi mungkin masih cukup. - person syntonym; 27.03.2015
comment
saat menulis penjelasannya juga memperhatikan hal itu. benar tentang rekursif, akan melakukannya juga berulang - person Udy; 27.03.2015
comment
OP meminta rekursi - person Moshe Carmeli; 27.03.2015
comment
Benar, Stack vs Queue akan menjadi DFS vs BFS - person Udy; 27.03.2015
comment
Jawaban yang bagus. Catatan: Jika Anda ingin menyimulasikan pengurutan pencarian kedalaman-pertama LIFO, maka Stack harus digunakan sebagai ganti Antrian. Atau gunakan Deque untuk menyimulasikan urutan tepat dari fungsi rekursif. Antrian akan melakukan pencarian yang mengutamakan luas. - person Shashank; 27.03.2015
comment
@MosheCarmeli Dia menggunakan istilah dalam judul untuk menunjukkan bahwa dia ingin melintasi semua subdikte, tetapi pemrosesan rekursif tidak kompatibel dengan dikte dalam yang sewenang-wenang dengan python, sedangkan solusi berulang akan berfungsi. Saya rasa dia tidak menggunakan istilah recursive teknis tetapi untuk menjelaskan masalahnya. - person syntonym; 27.03.2015