Saya memiliki kamus yang agak besar dan bersarang. Seorang pengguna menentukan "pemetaan" dalam file teks di mana dia memberi tahu saya nilai apa dalam kamus yang akan disalin.

Contoh baris: a/b/c/d -> A/B/C

Jadi dengan Python saya akan memastikan kunci target ada dan kemudian menulis

myDict["A"]["B"]["C"] = myDict["a"]["b"]["c"]["d"]

Apakah ada fungsi untuk mengotomatisasi ini dan menggunakan daftar kunci untuk mengakses bagian tertentu dari kamus? Sesuatu seperti

source = ["a", "b", "c", "d"]
target = ["A", "B", "C"]
myDict.whereToGo(target) = myDict.whereToGo(source)

Sunting: Sudah dijawab, tetapi untuk memperjelas bagi pembaca di masa mendatang. Saya ingin menggabungkan file xml dan json. Setelah memilih metode untuk mengonversi xml ke json, saya mendapatkan informasi yang diberikan dua kali (sekali dari json asli dan sekali dari xml asli), tetapi hanya satu yang "benar". Pengguna diberi opsi untuk menentukan pemetaan dari xml ke file json (dalam kasus saya a/b/c/d dalam file xml ke A/B/C dalam file json, tetapi mungkin ada beberapa baris dalam teks itu mengajukan).

0
Stefan 11 Agustus 2017, 11:13

2 jawaban

Jawaban Terbaik

Ya, Anda dapat membangun fungsi untuk mengambil nilai bersarang:

def whereToGo(key_list, dict):
    if key_list:
        key = key_list.pop(0)
        value = whereToGo(key_list, dict[key])
        return value

    else:
        return dict
2
Dror Av. 11 Agustus 2017, 08:30

Pertanyaan Anda tidak terlalu jelas. Mengambil contoh Anda secara harfiah, Anda dapat menjawabnya seperti ini:

# "Make the below happen"
# lookup["A"]["B"]["C"] = original["a"]["b"]["c"]["d"]
import collections

def infinite_dict():
    return collections.defaultdict(infinite_dict)

original = {'a': {'b': {'c': {'d': 'value!'}}}}
lookup = infinite_dict()
lookup["A"]["B"]["C"] = original["a"]["b"]["c"]["d"]
assert lookup['a']['b']['c'] == 'value!'

Jika di sisi lain Anda ingin memberikan objek ajaib yang melakukan pemetaan dinamis dari mis .:

# for any given x, y, z
assert lookup[x][y][z] == original[z][y][x][42]

Maka ini mungkin juga, tetapi lebih terlibat, dan mungkin ide yang buruk. Disertakan sebagai kisah peringatan, harap pikirkan kembali pendekatan Anda:

Please no

import inspect

class RemappedDict(object):
     def __init__(self, lookup, needed=None, args=()):
         '''
         source is the base dict used to index into
         '''
         if needed is None:
             needed = len(inspect.getargspec(lookup).args)
         if needed < 1:
             raise ValueError('This is not going to go well')
         self.__lookup = lookup
         self.__needed = needed
         self.__args = args

     def __getitem__(self, item):
         new_args = self.__args + (item,)
         new_needed = self.__needed - 1
         if not new_needed:
             return self.__lookup(*new_args)
         return RemappedDict(self.__lookup, new_needed, new_args)

Maka Anda bisa menggunakan ini seperti

original = {'a': {'b': {'c': {'d': 'value!'}}}}
logic = lambda x, y, z: original[z][y][x]["d"]
lookup = RemappedDict(logic)
assert lookup['c']['b']['a'] == 'value!'
0
Cireo 11 Agustus 2017, 08:56