यह काम करने वाला नहीं है:
मर्ज केवल मैपिंग के लिए YAML विनिर्देशों द्वारा समर्थित है और अनुक्रमों के लिए नहीं
आप <<
कुंजी / मान विभाजक :
और एक मान के बाद मर्ज की कुंजी के द्वारा पूरी तरह से चीजों को मिला रहे हैं जो एक संदर्भ है और फिर उसी इंडेंटेशन स्तर पर एक सूची के साथ जारी रखें
यह सही नहीं है YAML:
combine_stuff:
x: 1
- a
- b
तो आपके उदाहरण वाक्यविन्यास भी एक YAML विस्तार प्रस्ताव के रूप में मतलब नहीं होगा।
यदि आप कई सरणियों को मर्ज करने जैसा कुछ करना चाहते हैं, तो आप एक वाक्यविन्यास पर विचार करना चाह सकते हैं जैसे:
combined_stuff:
- <<: *s1, *s2
- <<: *s3
- d
- e
- f
जहां s1
, s2
, s3
दृश्यों (नहीं दिखाया गया है) कि आप एक नया अनुक्रम में अलग करना चाहते हैं और उसके बाद है पर एंकर हैं d
, e
और f
कि के साथ जोड़ दिया। लेकिन YAML पहले इस तरह की संरचनाओं की गहराई का समाधान कर रहा है, इसलिए मर्ज कुंजी के प्रसंस्करण के दौरान कोई वास्तविक संदर्भ उपलब्ध नहीं है। आपके लिए कोई ऐसी सरणी / सूची उपलब्ध नहीं है जहाँ आप संसाधित मान (एंकर अनुक्रम) संलग्न कर सकते हैं।
आप @dreftymac द्वारा प्रस्तावित दृष्टिकोण को अपना सकते हैं, लेकिन इसका बहुत बड़ा नुकसान है कि आपको किसी तरह यह जानने की जरूरत है कि कौन से निहित दृश्यों को समतल करने की आवश्यकता है (यानी लोड किए गए डेटा संरचना के मूल से "पथ" को जनक अनुक्रम तक ले जाएं,) या कि आप पुनरावर्ती लोड किए गए डेटा संरचना को नेस्टेड सरणियों / सूचियों के लिए खोजते हुए चलते हैं और उन सभी को अंधाधुंध रूप से समतल करते हैं।
एक बेहतर समाधान आईएमओ डेटा संरचनाओं को लोड करने के लिए टैग का उपयोग करना होगा जो आपके लिए सपाट हो। यह स्पष्ट रूप से यह बताने के लिए अनुमति देता है कि चपटा होने की क्या आवश्यकता है और क्या नहीं और आपको इस बात पर पूरा नियंत्रण देता है कि क्या यह समतल लोडिंग के दौरान किया गया है, या पहुंच के दौरान किया गया है। कौन सा चुनना है जो समय और भंडारण स्थान में कार्यान्वयन और दक्षता में आसानी का मामला है। यह वही ट्रेड-ऑफ है जिसे मर्ज की प्रमुख विशेषता को लागू करने के लिए किए जाने की आवश्यकता है और ऐसा कोई भी समाधान नहीं है जो हमेशा सबसे अच्छा हो।
उदाहरण के लिए, मेरा ruamel.yaml
पुस्तकालय अपने सुरक्षित-लोडर का उपयोग करते समय लोडिंग के दौरान ब्रूट बल मर्ज-डिक्ट्स का उपयोग करता है, जिसके परिणामस्वरूप मर्ज किए गए शब्दकोशों में सामान्य पायथन डाइक होते हैं। यह मर्जिंग अप-फ्रंट किया जाना है, और डेटा (स्पेस अक्षम) को डुप्लिकेट करता है, लेकिन वैल्यू लुकअप में तेज है। राउंड-ट्रिप-लोडर का उपयोग करते समय, आप मर्ज किए गए मर्ज को डंप करने में सक्षम होना चाहते हैं, इसलिए उन्हें अलग रखने की आवश्यकता है। राउंड-ट्रिप-लोडिंग के परिणामस्वरूप लोड किए गए डिएटास्ट्रक्चर जैसा तानाशाह अंतरिक्ष में कुशल है, लेकिन उपयोग में धीमा है, क्योंकि इसे मर्ज में ही नहीं मिल पाने वाली कुंजी को खोजने की कोशिश करने और देखने की जरूरत है (और यह कैश्ड नहीं है, इसलिए यह हर बार किया जाना चाहिए)। बेशक इस तरह के विचार अपेक्षाकृत छोटे कॉन्फ़िगरेशन फ़ाइलों के लिए बहुत महत्वपूर्ण नहीं हैं।
निम्नलिखित वस्तुओं को टैग के साथ वस्तुओं का उपयोग करते हुए अजगर में सूचियों के लिए एक मर्ज की योजना लागू होती है, जो उन वस्तुओं flatten
पर पुनरावृत्ति करता है जो सूची और टैग किए गए हैं toflatten
। इन दो टैगों का उपयोग करके आपके पास YAML फाइल हो सकती है:
l1: &x1 !toflatten
- 1
- 2
l2: &x2
- 3
- 4
m1: !flatten
- *x1
- *x2
- [5, 6]
- !toflatten [7, 8]
(प्रवाह बनाम ब्लॉक शैली अनुक्रमों का उपयोग पूरी तरह से मनमाना है और लोड किए गए परिणाम पर कोई प्रभाव नहीं है)।
जब उन वस्तुओं के बारे में पुनरावृति होती है जो कुंजी के लिए मूल्य हैं, तो m1
यह "अनुक्रम" में अनुक्रम के साथ टैग किया जाता है toflatten
, लेकिन एकल सूची के रूप में अन्य सूचियों (उपनाम या नहीं) को प्रदर्शित करता है।
इसे प्राप्त करने के लिए पायथन कोड के साथ एक संभव तरीका:
import sys
from pathlib import Path
import ruamel.yaml
yaml = ruamel.yaml.YAML()
@yaml.register_class
class Flatten(list):
yaml_tag = u'!flatten'
def __init__(self, *args):
self.items = args
@classmethod
def from_yaml(cls, constructor, node):
x = cls(*constructor.construct_sequence(node, deep=True))
return x
def __iter__(self):
for item in self.items:
if isinstance(item, ToFlatten):
for nested_item in item:
yield nested_item
else:
yield item
@yaml.register_class
class ToFlatten(list):
yaml_tag = u'!toflatten'
@classmethod
def from_yaml(cls, constructor, node):
x = cls(constructor.construct_sequence(node, deep=True))
return x
data = yaml.load(Path('input.yaml'))
for item in data['m1']:
print(item)
कौन से आउटपुट:
1
2
[3, 4]
[5, 6]
7
8
जैसा कि आप देख सकते हैं कि आप उस क्रम में देख सकते हैं, जिसमें चपटेपन की आवश्यकता होती है, आप या तो किसी अन्य को टैग किए गए अनुक्रम का उपयोग कर सकते हैं या आप टैग किए गए अनुक्रम का उपयोग कर सकते हैं। YAML आपको करने की अनुमति नहीं देता है:
- !flatten *x2
, अर्थात् एक लंगर अनुक्रम को टैग करें, क्योंकि यह अनिवार्य रूप से इसे एक अलग डेटास्ट्रक्चर में बना देगा।
स्पष्ट टैग का उपयोग करना IMO से अच्छा है क्योंकि कुछ मैजिक, जैसे कि YAML मर्ज कीज़ के साथ चल रहा है <<
। यदि आपके पास अब कुछ नहीं है तो आपको हुप्स के माध्यम से जाना होगा यदि आपके पास एक मैपिंग के साथ एक YAML फ़ाइल होती है जिसमें एक कुंजी होती है
<<
जिसे आप मर्ज की तरह कार्य नहीं करना चाहते हैं, उदाहरण के लिए जब आप सी ऑपरेटरों के मानचित्रण को उनके विवरण के लिए बनाते हैं अंग्रेजी में (या कुछ अन्य प्राकृतिक भाषा)।