নেস্টেড ডিফল্ট ডিটিক্টডিক্ট


129

ডিফল্টডিক্টিকে ডিফল্টডিক্ট্টের জন্য ডিফল্ট করার উপায় কি আছে? (অর্থাত্ অসীম-স্তরের পুনরাবৃত্ত ডিফল্টডিক্ট?)

আমি করতে সক্ষম হতে চাই:

x = defaultdict(...stuff...)
x[0][1][0]
{}

সুতরাং, আমি এটি করতে পারি x = defaultdict(defaultdict)তবে এটি কেবল দ্বিতীয় স্তরের:

x[0]
{}
x[0][0]
KeyError: 0

এমন রেসিপি রয়েছে যা এটি করতে পারে। তবে এটি কেবল সাধারণ ডিফল্টডিক্ট আর্গুমেন্ট ব্যবহার করেই করা যায়?

নোট এটি একটি অসীম-স্তরের পুনরাবৃত্তি ডিফল্টডিক্ট কীভাবে করবেন তা জিজ্ঞাসা করছে, তাই এটি পাইথনের থেকে পৃথক: ডিফল্টডিক্ট্টের ডিফল্টডিক্ট? এটি কীভাবে দ্বি-স্তরের ডিফল্টডিক্ট্ট করতে হয়।

আমি সম্ভবত গুচ্ছ প্যাটার্নটি ব্যবহার করে শেষ করব , কিন্তু যখন বুঝতে পারলাম আমি কীভাবে এটি করতে হয় তা জানিনা, এটি আমার আগ্রহী হয়ে উঠল ।



2
আসলেই নয় ... কেন তা নির্দেশ করার জন্য প্রশ্নের সাথে যুক্ত করা তথ্য। যদিও এটি একটি দরকারী প্রশ্ন।
করলি ব্রিগম্যান

উত্তর:


168

স্তরের একটি নির্বিচার সংখ্যার জন্য:

def rec_dd():
    return defaultdict(rec_dd)

>>> x = rec_dd()
>>> x['a']['b']['c']['d']
defaultdict(<function rec_dd at 0x7f0dcef81500>, {})
>>> print json.dumps(x)
{"a": {"b": {"c": {"d": {}}}}}

অবশ্যই আপনি একটি ল্যাম্বদা দিয়ে এটি করতে পারেন, তবে আমি ল্যাম্বডাস কম পাঠযোগ্য বলে মনে করি। যে কোনও ক্ষেত্রে এটি দেখতে এই রকম হবে:

rec_dd = lambda: defaultdict(rec_dd)

1
প্রকৃতপক্ষে একটি নিখুঁত উদাহরণ, ধন্যবাদ। আপনি কি দয়া করে এটি মামলায় প্রসারিত করতে পারেন, যে তথ্যটি জসন থেকে ডিফল্টডিক্টের ডিফল্টডিকেটে লোড হয়?
ডেভিড বেলোহরাদ

4
এক নোট. আপনি যদি এই কোডটি ব্যবহার করার চেষ্টা করছেন তবে পিকিংয়ের lambdaকাজ হবে না।
ভাইচেস্লাভ কন্ড্রাটুক

166

এখানে অন্যান্য উত্তরগুলি আপনাকে কীভাবে এমন একটি তৈরি করবেন তা জানায় defaultdictযা "অসীম অনেকগুলি" রয়েছে defaultdictতবে তারা আমার প্রাথমিক প্রয়োজন হতে পারে যা কেবল দ্বি-গভীরতার ডিফল্টডিক্ট্টিক্ট ছিল তা সম্বোধন করতে ব্যর্থ হয়।

আপনি খুঁজছেন হতে পারে:

defaultdict(lambda: defaultdict(dict))

যে কারণে আপনি এই নির্মাণ পছন্দ করতে পারেন তা হ'ল:

  • এটি পুনরাবৃত্তির সমাধানের চেয়ে বেশি স্পষ্ট এবং তাই পাঠকের কাছে সম্ভবত আরও বোধগম্য।
  • এটি এর "পাতাকে" defaultdictএকটি অভিধান ছাড়া অন্য কিছু হতে সক্ষম করে , যেমন :: defaultdict(lambda: defaultdict(list))বা:defaultdict(lambda: defaultdict(set))

3
defaultdict (ল্যাম্বদা: defaultdict (তালিকা)) সঠিক ফর্ম?
যুবরাজ লোগানাথন

ওফস, হ্যাঁ, lambdaফর্মটি সঠিক - কারণ defaultdict(something)অভিধানের মতো একটি বস্তু defaultdictপ্রত্যাবর্তন করে তবে কলযোগ্য বলে প্রত্যাশা করে! ধন্যবাদ!
ক্রিস ডব্লু।

4
এটি অন্য প্রশ্নের সম্ভাব্য সদৃশ হিসাবে চিহ্নিত হয়েছে ... তবে এটি আমার আসল প্রশ্ন নয়। আমি জানতাম কীভাবে দ্বি-স্তরের ডিফল্টডিক্ট্ট তৈরি করতে হয়; যা আমি জানতাম না তা কীভাবে এটি পুনরাবৃত্ত করতে পারে। এই উত্তরটি প্রকৃতপক্ষে
স্ট্যাকওভারফ্লো / সেকশন /

ল্যাম্বডা পদ্ধতির পিছনে ফিরে আসা একটি জিনিস হ'ল এটি যে জিনিসগুলি উত্পন্ন করে dict(result)
সেগুলিকে আচ্ছাদন

54

এটি করার জন্য একটি নিফটি কৌশল আছে:

tree = lambda: defaultdict(tree)

তারপর আপনি আপনার তৈরি করতে পারেন xসঙ্গে x = tree()


22

ব্রেনবার্নের সমাধানের মতো, তবে ভেরিয়েবলের নামটি treeদু'বার ধারণ করে না , সুতরাং এটি ভেরিয়েবল অভিধানে পরিবর্তনের পরেও কাজ করে:

tree = (lambda f: f(f))(lambda a: (lambda: defaultdict(a(a))))

তারপর আপনি প্রতিটি নতুন তৈরি করতে পারেন xসঙ্গে x = tree()


জন্য defসংস্করণ, আমরা ফাংশন অবসান সুযোগ ব্যবহার ত্রুটি যেখানে বিদ্যমান দৃষ্টান্ত যদি কাজ করা বন্ধ করে থেকে ডাটা স্ট্রাকচার রক্ষা করতে পারেন treeনাম রিবাউন্ড হয়। দেখে মনে হচ্ছে:

from collections import defaultdict

def tree():
    def the_tree():
        return defaultdict(the_tree)
    return the_tree()

4
আমাকে এটি সম্পর্কে ভাবতে হবে (এটি কিছুটা জটিল)। তবে আমি মনে করি আপনার বক্তব্যটি যদি x = ট্রি () করে তবে তারপরে কেউ পরে এসে গাছে = কিছুই না, এইটি এখনও কাজ করবে, এবং তা হবে না?
করলি ব্রিগম্যান

11

আমি আরও ওওপি-স্টাইলযুক্ত বাস্তবায়ন প্রস্তাব করব, যা অসীম বাসা বাঁধার পাশাপাশি যথাযথ ফর্ম্যাটেড সমর্থন করে repr

class NestedDefaultDict(defaultdict):
    def __init__(self, *args, **kwargs):
        super(NestedDefaultDict, self).__init__(NestedDefaultDict, *args, **kwargs)

    def __repr__(self):
        return repr(dict(self))

ব্যবহার:

my_dict = NestedDefaultDict()
my_dict['a']['b'] = 1
my_dict['a']['c']['d'] = 2
my_dict['b']

print(my_dict)  # {'a': {'b': 1, 'c': {'d': 2}}, 'b': {}}

1
ঝরঝরে! আমি পাসথ্রুটি যুক্ত করেছি *argsএবং **kwargsএটি এটি defaultdictকীওয়ার্ড আর্গুমেন্টের সাহায্যে একটি ডিক তৈরি করতে যেমন, এর মতো কাজ করতে দেয় । এটি NestedDefaultDictপ্রবেশের জন্য দরকারীjson.load
সিপরিয়ান টমোইগা

0

একটি recursive ডিফল্ট ডেককে একটি সাধারণ ডকে রূপান্তর করতে এখানে একটি পুনরাবৃত্ত ফাংশন

def defdict_to_dict(defdict, finaldict):
    # pass in an empty dict for finaldict
    for k, v in defdict.items():
        if isinstance(v, defaultdict):
            # new level created and that is the new value
            finaldict[k] = defdict_to_dict(v, {})
        else:
            finaldict[k] = v
    return finaldict

defdict_to_dict(my_rec_default_dict, {})

0

আমি এন্ড্রু এর উত্তর এখানে ভিত্তি করে । আপনি যদি কোনও জেসন বা কোনও বিদ্যমান ডিক থেকে নেস্টার ডিফল্টটিতে ডেটা লোড করতে খুঁজছেন তবে এই উদাহরণটি দেখুন:

def nested_defaultdict(existing=None, **kwargs):
    if existing is None:
        existing = {}
    if not isinstance(existing, dict):
        return existing
    existing = {key: nested_defaultdict(val) for key, val in existing.items()}
    return defaultdict(nested_defaultdict, existing, **kwargs)

https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.