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


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.