एक ही समय में कई चर घोषित करने का अधिक सुरुचिपूर्ण तरीका


140

"एक ही समय" पर कई चर घोषित करने के लिए मैं यह करूंगा:

a, b = True, False

लेकिन अगर मुझे बहुत अधिक चर घोषित करना पड़ा, तो यह कम और कम सुरुचिपूर्ण हो गया:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True

क्या ऐसा करने का एक बेहतर / सुरुचिपूर्ण / सुविधाजनक तरीका है?

यह बहुत ही बुनियादी होना चाहिए, लेकिन अगर मैं चर को संग्रहीत करने के लिए एक सूची या टपल का उपयोग करता हूं, तो मुझे कैसे संपर्क करना होगा ताकि मैं इसके लिए उपयोगी हो जाऊं:

aList = [a,b]

मान्य नहीं है, मुझे करना होगा:

a, b = True, True

या मैं क्या याद कर रहा हूँ?


उन मूल्यों को संग्रहीत करने के लिए एक सूची का उपयोग करें? एक शब्दकोष? ए (नाम) टपल?
जेफ मर्काडो

@ क्रिस: मैं वहाँ जा रहा था। :)
जेफ मर्काडो

@ जेफ: शायद, लेकिन मुझे नहीं पता कि यह कैसे करना है कि ऐसा लगता है कि उन्हें एक सूची से संबंधित होने के लिए परिभाषित करना होगा (मैं निश्चित रूप से गलत हो सकता है)
ट्रूफा

3
@ ट्राफा: यदि आप यह घोषित करने जा रहे हैं कि मूल्यों को संग्रहीत करने के लिए कई चर, यह पहले से ही एक संकेत है तो आपको अन्य भंडारण विकल्पों पर विचार करना चाहिए।
जेफ मर्काडो

1
@ user470379 - मैंने यह माना कि नाम केवल उदाहरण कोड के लिए थे, और यह कि ट्रूफ़ा अपने असली कोड में उन नामों का उपयोग नहीं कर रहा है।
क्रिस लुत्ज़

जवाबों:


52

जैसा कि दूसरों ने सुझाव दिया है, यह संभावना नहीं है कि बूलियन मूल्यों के साथ 10 अलग-अलग स्थानीय चर का उपयोग करना आपकी दिनचर्या लिखने का सबसे अच्छा तरीका है (खासकर यदि उनके पास वास्तव में एक-अक्षर का नाम है :)

आप जो कर रहे हैं, उसके आधार पर, इसके बजाय एक शब्दकोश का उपयोग करना समझ में आता है। उदाहरण के लिए, यदि आप एक-अक्षर के झंडे के सेट के लिए बूलियन प्रीसेट मान सेट करना चाहते हैं, तो आप ऐसा कर सकते हैं:

>>> flags = dict.fromkeys(["a", "b", "c"], True)
>>> flags.update(dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

यदि आप चाहें, तो आप इसे एक असाइनमेंट स्टेटमेंट के साथ भी कर सकते हैं:

>>> flags = dict(dict.fromkeys(["a", "b", "c"], True),
...              **dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

दूसरा पैरामीटर इसके लिए dictपूरी तरह से डिज़ाइन नहीं किया गया है: यह वास्तव में आपको कीवर्ड तर्कों जैसे शब्दकोष के व्यक्तिगत तत्वों को ओवरराइड करने की अनुमति देने के लिए है d=False। ऊपर दिए गए कोड, अभिव्यक्ति के परिणाम **को कीवर्ड तर्कों के एक सेट के रूप में दिखाते हैं, जिन्हें फंक्शन कहा जाता है। यह निश्चित रूप से शब्दकोश बनाने का एक विश्वसनीय तरीका है, और लोग कम से कम इस मुहावरे को स्वीकार करते हुए प्रतीत होते हैं, लेकिन मुझे संदेह है कि कुछ इसे यूनीथोनिक मान सकते हैं। </disclaimer>


फिर भी एक अन्य दृष्टिकोण, जो संभवतः सबसे सहज है, यदि आप इस पैटर्न का अक्सर उपयोग कर रहे हैं, तो अपने डेटा को ध्वज के नामों की सूची के रूप में परिभाषित करना है ( True, False) ध्वज नामों (एकल-वर्ण स्ट्रिंग्स) के लिए मैप किया गया। आप फिर इस डेटा परिभाषा को एक उल्टे शब्दकोष में बदल देते हैं, जो ध्वज के नामों को ध्वज मानों में बदल देता है। यह पूरी तरह से एक नेस्टेड सूची समझ के साथ किया जा सकता है, लेकिन यहां एक बहुत ही पठनीय कार्यान्वयन है:

>>> def invert_dict(inverted_dict):
...     elements = inverted_dict.iteritems()
...     for flag_value, flag_names in elements:
...         for flag_name in flag_names:
...             yield flag_name, flag_value
... 
>>> flags = {True: ["a", "b", "c"], False: ["d", "e"]}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

फ़ंक्शन invert_dictएक जनरेटर फ़ंक्शन है । यह उत्पन्न करता है , या पैदावार - जिसका अर्थ है कि यह बार-बार - मूल्य-मान जोड़े देता है। वे कुंजी-मूल्य जोड़े प्रारंभिक flagsशब्दकोष के दो तत्वों की सामग्री का विलोम हैं । उन्हें dictकंस्ट्रक्टर में खिलाया जाता है । इस मामले में dictकंस्ट्रक्टर ऊपर से अलग तरह से काम करता है क्योंकि इसे एक तर्क के बजाय एक इटैलर खिलाया जा रहा है।


@ क्रिस लूत्ज की टिप्पणी पर आकर्षित: यदि आप वास्तव में एकल-चरित्र मूल्यों के लिए इसका उपयोग कर रहे हैं, तो आप वास्तव में कर सकते हैं

>>> flags = {True: 'abc', False: 'de'}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

यह काम करता है क्योंकि पायथन स्ट्रिंग्स चलने योग्य हैं , जिसका अर्थ है कि उन्हें मूल्य के माध्यम से स्थानांतरित किया जा सकता है। एक स्ट्रिंग के मामले में, मान स्ट्रिंग में व्यक्तिगत वर्ण हैं। इसलिए जब उन्हें पुनरावृत्तियों के रूप में व्याख्या की जा रही है, जैसे कि इस मामले में जहां उनका उपयोग लूप में किया जा रहा है, ['a', 'b', 'c']और 'abc'प्रभावी रूप से समतुल्य है। एक और उदाहरण तब होगा जब उन्हें एक समारोह में पारित किया जाएगा, जो एक पुनरावृत्त लेता है, जैसे tuple

मैं व्यक्तिगत रूप से ऐसा नहीं करूंगा क्योंकि यह सहज रूप से नहीं पढ़ता है: जब मैं एक स्ट्रिंग देखता हूं, तो मुझे उम्मीद है कि इसे एक सूची के बजाय एकल मूल्य के रूप में उपयोग किया जाएगा। इसलिए मैं पहली पंक्ति को देखता हूं और सोचता हूं "ठीक है, इसलिए एक सच्चा झंडा और एक गलत झंडा है।" इसलिए हालांकि यह एक संभावना है, मुझे नहीं लगता कि यह जाने का रास्ता है। उल्टा, यह पुनरावृत्तियों और पुनरावृत्तियों की अवधारणाओं को अधिक स्पष्ट रूप से समझाने में मदद कर सकता है।


फ़ंक्शन को invert_dictइस तरह परिभाषित करना कि यह वास्तव में एक शब्दकोश देता है या तो एक बुरा विचार नहीं है; मैं ज्यादातर ऐसा नहीं करता था क्योंकि यह वास्तव में यह समझाने में मदद नहीं करता है कि दिनचर्या कैसे काम करती है।


जाहिर तौर पर पायथन 2.7 में शब्दकोश की समझ है, जो उस कार्य को कार्यान्वित करने के लिए एक अत्यंत संक्षिप्त तरीका है। यह पाठक के लिए एक अभ्यास के रूप में छोड़ दिया गया है, क्योंकि मेरे पास 2.7 स्थापित नहीं है :)

आप कभी-कभी बहुमुखी इटर्स्टूल मॉड्यूल से कुछ कार्यों को भी जोड़ सकते हैं । जैसा कि वे कहते हैं, इसमें एक से अधिक तरीके हैं । रुको, अजगर लोग ऐसा नहीं कहते हैं। खैर, यह कुछ मामलों में वैसे भी सच है। मुझे लगता है कि Guido हैथ ने हमें शब्दकोष समझने की अनुमति दी है ताकि ऐसा करने के लिए वन ऑब्ब्यूस वे होगा।


1
ध्यान दें कि ['a', 'b', 'c']करने के लिए छोटा किया जा सकता list('abc')है, जो प्रेरित def truth_values(trues, falses): d = dict.from_keys(list(trues), True); d.update(dict.from_keys(list(falses), False)); return dके रूप में इस्तेमालvalues = truth_values("abc", "de")
क्रिस लुट्ज़

बहुत बहुत धन्यवाद यह एक बहुत व्यापक उत्तर की तरह लगता है, मैं इसे अच्छा लुक दूंगा और प्रयोग करूंगा कि आप क्या गद्य बोल रहे हैं, आप क्या कह रहे हैं, जबकि यह शायद सच है, यह स्वाभाविक नहीं हो सकता है इसलिए मुझे करना होगा थोड़ा पढ़िए और तब तक खेलिए, जब तक कि मुझे पूरी तरह से वही नहीं मिल जाता है, जो विशेष रूप से उन शब्दकोशों के बाद से होता है, जो अजगर में मेरी कमजोरियों में से एक हैं। बहुत बहुत धन्यवाद, मैं वापस आ
जाऊंगा

5
@intuited मैं आपके जवाब से भड़क गया हूं: आप ओपी की तुलना में एक और समस्या को परिभाषित करते हैं और आप इस दूसरी समस्या का लंबा जवाब देने में प्रसन्न होते हैं। वह एक शब्दकोश में तार और मूल्यों को जोड़ना नहीं चाहता है, वह एक पहचानकर्ता और प्रत्येक के लिए एक मूल्य के साथ वस्तुओं को बनाना चाहता है।
eyquem

5
@eyquem: लंबे उत्तर खराब हैं? चिकित्सक, अपने आप को चंगा!
जॉन मैकिन

5
इस सवाल का जवाब नहीं है, और यह संरक्षण है। नीचे उत्तर देखें
कोडु

225
a, b, c, d, e, g, h, i, j = (True,)*9
f = False

21
@ इमरई ट्रेलिंग कॉमा नोटेशन (d,)एक आइटम टपल बनाता है, जो एक अनुक्रम प्रकार है। अन्य प्रकारों में अनुक्रम प्रकार जोड़ और गुणा का समर्थन करते हैं।
डुओजमो

36
एलिगेंट ट्रिक, लेकिन लिस्ट जैसे म्यूटेबल एलिमेंट्स पर इसे इस्तेमाल करने के लिए जागरूक रहें। उदाहरण के लिए a, b, c = ([],)*33 सूची उदाहरण नहीं बनाता है a, लेकिन बनाता है , bऔर cउसी उदाहरण की ओर इशारा करता है।
Zac

5
मुझे आश्चर्य है कि मैं अपना समय बर्बाद कर रहा हूं / अपने अजगर कोड uber pythonic बनाने की कोशिश कर रहा हूं?
सरोज

3
@Zac का सही उपयोग करना a, b, c = ([] for i in range(3))स्रोत । स्थिरता के लिए, आप इस उत्तर के लिए इसका एक प्रकार भी उपयोग कर सकते हैं, अर्थात a,b,c,d,e,g,h,i,j = (True for i in range(9)) f=(False i in range(1))
Novice C

यह एक उदाहरण है कि मैं क्यों अजगर से प्यार करता हूं, केवल हाल ही में इसका उपयोग कर रहा हूं .. मैं चाहता हूं कि यह पहले ही शुरू हो जाए .. लेकिन परियोजना के आधार पर वेब विकास अलग-अलग होता है।
गुस्सा 84

52

एक सूची / शब्दकोश का उपयोग करें या अपनी परिभाषित की गई सामग्री को संक्षिप्त करने के लिए अपने स्वयं के वर्ग को परिभाषित करें, लेकिन यदि आपको उन सभी चर की आवश्यकता है जो आप कर सकते हैं:

a = b = c = d = e = g = h = i = j = True
f = False

1
var केवल True और False पर सेट नहीं होंगे।
एन १.१

1
@ N1.1: मैं समझ नहीं पा रहा था कि आपका क्या मतलब है।
ट्रूफा

@ ट्रूफा यदि वे केवल सही / गलत पर सेट हैं, तो सुझाया गया तरीका सही है, लेकिन क्या होगा अगर चर अलग-अलग चीजों के लिए सेट किए गए हों?
एन 1.1

@ N1.1: ओह, मुझे तुम्हारा क्या मतलब है, स्पष्टीकरण के लिए धन्यवाद! इस मामले में, वे सभी बूल हैं, लेकिन यह जानना अच्छा है। धन्यवाद
Trufa

5
यह एक खतरनाक पैटर्न (यद्यपि काम करने का उदाहरण) क्यों है, इसकी व्याख्या के लिए, कुख्यात बिग
डूजोमो

10

यह @ जेफ एम की टिप्पणियों और मेरी टिप्पणियों पर विस्तार है।

जब आप ऐसा करते हैं:

a, b = c, d

यह टपल पैकिंग और अनपैकिंग के साथ काम करता है। आप पैकिंग और अनपैकिंग चरणों को अलग कर सकते हैं:

_ = c, d
a, b = _

पहली पंक्ति एक टपल बनाती है _जिसमें दो तत्व होते हैं, पहला मूल्य के साथ cऔर दूसरा मूल्य के साथ d। दूसरी पंक्ति unpacks _चर में टपल aऔर b। इससे आपकी एक बड़ी लाइन टूट जाती है:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True, True, True, True

दो छोटी लाइनों में:

_ = True, True, True, True, True, False, True, True, True, True
a, b, c, d, e, f, g, h, i, j = _

यह आपको पहली पंक्ति के समान सटीक परिणाम देगा (यदि आप एक हिस्से में मान या चर जोड़ते हैं तो उसी अपवाद को शामिल करते हैं लेकिन दूसरे को अपडेट करना भूल जाते हैं)। हालांकि, इस विशिष्ट मामले में, यान का जवाब शायद सबसे अच्छा है।

यदि आपके पास मूल्यों की सूची है, तो आप अभी भी उन्हें अनपैक कर सकते हैं। आपको बस इसे पहले एक ट्यूपल में बदलना होगा। उदाहरण के लिए, निम्नलिखित क्रमशः प्रत्येक के aमाध्यम से 0 और 9 के बीच एक मान प्रदान करेगा j:

a, b, c, d, e, f, g, h, i, j = tuple(range(10))

संपादित करें: तत्व 5 (चर f) को छोड़कर उन सभी को सही मानने के लिए नीट ट्रिक :

a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10))

मुझे नहीं पता था कि पिछले एक संभव था, मैं इसे निश्चित रूप से कोशिश करूँगा, यह वास्तव में एक साफ चाल है और यह काम आ सकता है!
ट्रूफा

5

जब लोग "एक सूची या टपल या अन्य डेटा संरचना का उपयोग करने" का सुझाव दे रहे हैं, तो वे क्या कह रहे हैं, जब आपके पास बहुत सारे अलग-अलग मूल्य हैं जिनकी आप परवाह करते हैं, उन सभी को अलग-अलग नाम देना क्योंकि स्थानीय चर सबसे अच्छा तरीका नहीं हो सकता है। यह काम करने हैं।

इसके बजाय, आप उन्हें एक बड़ी डेटा संरचना में एक साथ इकट्ठा करना चाह सकते हैं जिसे एकल स्थानीय चर में संग्रहीत किया जा सकता है।

अंतर्ज्ञान से पता चलता है कि आप इसके लिए एक शब्दकोश का उपयोग कैसे कर सकते हैं, और क्रिस लुट्ज़ ने दिखाया कि अलग-अलग चर में अनपैक करने से पहले अस्थायी भंडारण के लिए एक टपल का उपयोग कैसे करें, लेकिन विचार करने के लिए एक और विकल्प है collections.namedtupleकि मूल्यों को अधिक स्थायी रूप से बंडल करने के लिए उपयोग करें।

तो आप कुछ ऐसा कर सकते हैं:

# Define the attributes of our named tuple
from collections import namedtuple
DataHolder = namedtuple("DataHolder", "a b c d e f g")

# Store our data
data = DataHolder(True, True, True, True, True, False, True)

# Retrieve our data
print(data)
print(data.a, data.f)

रियल कोड निश्चित रूप से "DataHolder" और वर्णमाला के अक्षरों की तुलना में अधिक सार्थक नामों का उपयोग करेगा।


आपके उत्तर के लिए धन्यवाद, मैं इसे एक विकल्प के रूप में देखूंगा, बात यह है कि ( इस विशेष मामले के लिए ) यह और उपयोगी संरचना के लिए उपयोगी नहीं हो सकता है। मैं बाद में टिप्पणी करूंगा कि यह कैसे निकला, फिर से बहुत धन्यवाद!
ट्रूफा

आप एक साधारण वर्ग के साथ एक ही काम कर सकते हैं - DataHolderबस परिभाषा थोड़ी अधिक मिलती है।
ncoghlan

4

वास्तव में समस्या क्या है?

क्या तुम सच में की जरूरत है या चाहते हैं 10 एक , , , , , एफ , जी , एच , मैं , जे , वहाँ कोई अन्य संभावना है, एक समय या किसी अन्य पर लिखने के लिए किया जाएगा, एक और लिखने और लिखने । ....

यदि मान सभी भिन्न हैं, तो आप छूट के लिए लिखने के लिए बाध्य होंगे

a = 12
b= 'sun'
c = A() #(where A is a class)
d = range(1,102,5)
e = (line in filehandler if line.rstrip())
f = 0,12358
g = True
h = random.choice
i = re.compile('^(!=  ab).+?<span>')
j = [78,89,90,0]

व्यक्तिगत रूप से "चर" को परिभाषित करना है।

या, किसी अन्य लेखन का उपयोग करने की आवश्यकता नहीं है _:

a,b,c,d,e,f,g,h,i,j =\
12,'sun',A(),range(1,102,5),\
(line for line in filehandler if line.rstrip()),\
0.12358,True,random.choice,\
re.compile('^(!=  ab).+?<span>'),[78,89,90,0]

या

a,b,c,d,e,f,g,h,i,j =\
(12,'sun',A(),range(1,102,5),
 (line for line in filehandler if line.rstrip()),
 0.12358,True,random.choice,
 re.compile('^(!=  ab).+?<span>'),[78,89,90,0])

यदि उनमें से कुछ का मूल्य समान होना चाहिए, तो क्या यह समस्या है कि इसे लिखना बहुत लंबा है

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True 

?

तो आप लिख सकते हैं:

a=b=c=d=e=g=h=i=k=j=True
f = False

मुझे समझ नहीं आ रहा है कि वास्तव में आपकी समस्या क्या है। यदि आप एक कोड लिखना चाहते हैं, तो आप निर्देशों और परिभाषाओं के लेखन द्वारा आवश्यक वर्णों का उपयोग करने के लिए बाध्य हैं। और क्या ?

मुझे आश्चर्य है कि अगर आपका प्रश्न यह संकेत नहीं है कि आप कुछ गलत समझ रहे हैं।

जब कोई लिखता है a = 10, तो कोई "स्मृति का हिस्सा जिसका मूल्य बदल सकता है" के अर्थ में एक चर नहीं बनाता है । यह निर्देश:

  • या तो प्रकार integerऔर मान 10 के ऑब्जेक्ट के निर्माण को ट्रिगर करता है और वर्तमान नाम स्थान में इस ऑब्जेक्ट के साथ एक नाम 'ए' का बंधन

  • या ऑब्जेक्ट 10 के नाम स्थान में 'a' नाम को फिर से असाइन करें (क्योंकि 'a' पूर्व में किसी अन्य ऑब्जेक्ट से बंधा हुआ था)

मैं कहता हूं कि क्योंकि मैं 10 पहचानकर्ताओं को परिभाषित करने के लिए उपयोगिता नहीं देखता हूं, बी, सी ... गलत या सच की ओर इशारा करते हुए। यदि निष्पादन के दौरान ये मूल्य नहीं बदलते हैं, तो 10 पहचानकर्ता क्यों? और अगर वे बदल जाते हैं, तो पहले पहचानकर्ताओं को क्यों परिभाषित किया जाता है ?, उन्हें तब बनाया जाएगा जब उन्हें जरूरत पड़ने पर पहले से परिभाषित न किया जाए

आपका प्रश्न मुझे अजीब लगता है


2

लगता है कि आप अपनी समस्या मेरे पास गलत तरीके से पहुँचा रहे हैं।

एक ट्यूपल का उपयोग करने के लिए अपने कोड को फिर से लिखें या सभी डेटा स्टोर करने के लिए एक वर्ग लिखें।


आप के लिए धन्यवाद आप कह सकते हैं कि कोड की एक झलक के बिना भी :) मैं समझता हूं कि यह आदर्श नहीं है, और मुझे सुधार करना पड़ सकता है लेकिन आपका जवाब वास्तव में सवाल हल नहीं करता है। मैं अपनी बात हालांकि मिलता है।
ट्रूफा

1
मैं कह सकता हूं कि ऐसा लगता है, हां। ऐसा लगता है कि यह क्या है। Refactoring संभवत: आपकी समस्या का समाधान करेगी। आपकी समस्या एक शैली का मुद्दा है, क्रियात्मक नहीं है, इसलिए काफी मेटाडेटिव के अलावा कुछ भी पेश करना कठिन है।
अमीरो

1

मुझे शीर्ष मतदान वाला उत्तर पसंद है; हालाँकि, यह सूची के साथ समस्याओं के रूप में दिखाया गया है।

  >> a, b = ([0]*5,)*2
  >> print b
  [0, 0, 0, 0, 0]
  >> a[0] = 1
  >> print b
  [1, 0, 0, 0, 0]

यह महान विवरण (यहां) में चर्चा की गई है , लेकिन सार यह है कि aऔर लौटने के bसाथ एक ही वस्तु हैं (उसी के लिए )। इसलिए, यदि आप एक इंडेक्स बदलते हैं, तो आप दोनों के इंडेक्स को बदल रहे हैं और , चूंकि वे जुड़े हुए हैं। इसे हल करने के लिए आप (स्रोत) कर सकते हैंa is bTrueid(a) == id(b)ab

>> a, b = ([0]*5 for i in range(2))
>> print b
[0, 0, 0, 0, 0]
>> a[0] = 1
>> print b
[0, 0, 0, 0, 0]

यह तब शीर्ष उत्तर के एक संस्करण के रूप में इस्तेमाल किया जा सकता है, जिसमें "वांछित" सहज परिणाम हैं

>> a, b, c, d, e, g, h, i = (True for i in range(9))
>> f = (False for i in range(1)) #to be pedantic

1

आपके मामले में, मैं YAML का उपयोग करूंगा।

यह कई मापदंडों से निपटने के लिए एक सुरुचिपूर्ण और पेशेवर मानक है। मान एक अलग फ़ाइल से लोड किए गए हैं। आप इस लिंक में कुछ जानकारी देख सकते हैं:

https://keleshev.com/yaml-quick-introduction

लेकिन यह Google के लिए आसान है, क्योंकि यह एक मानक है, इसके बारे में सैकड़ों जानकारी हैं, आप पा सकते हैं कि आपकी समझ में सबसे अच्छा क्या है। ;)

सादर।


हाय हेनरिक, एसओ में आपका स्वागत है, आपके उत्तर के लिए धन्यवाद! कृपया अपने अगले प्रश्न का उत्तर देने से पहले उत्तर लिखना सुनिश्चित करें !
डिग्गी।

0

जावास्क्रिप्ट की तरह आप भी अजगर में एक पंक्ति में कई बयानों का उपयोग कर सकते हैंa = 1; b = "Hello World"; c += 3

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.