टपल और अनपैकिंग
एक ऐसी लिस्ट जिसे बदला नहीं जा सकता — कहाँ इसकी ज़रूरत है, अनपैकिंग से इंडेक्स की जगह नाम इस्तेमाल करना, एक लाइन में अदला-बदली, और (5) बनाम (5,) का जाल।
आप कैसे सीखना चाहते हैं?
वह समस्या जिसे हम हल कर रहे हैं
तीन दिन के मौसम का हिसाब रखना है — हर दिन का नाम, तापमान और नमी (humidity)।
लिस्ट से हो जाता है: ["monday", 31.5, 78]। काम चल जाएगा, लेकिन दो बातें खटकती हैं।
पहली, यह लिस्ट बदली जा सकती है। सोमवार के रिकॉर्ड में कोई ग़लती से append कर दे तो Python कुछ नहीं कहेगा — जबकि एक रिकॉर्ड में चार चीज़ें होनी ही नहीं चाहिए। जो चीज़ बदलनी नहीं चाहिए, उसे ऐसे डिब्बे में रखना जो बदल सकता है, एक चुपचाप छिपा ख़तरा है।
दूसरी, अंदर से तीनों वैल्यू निकालने के लिए लिखना पड़ता है record[0], record[1], record[2] — नंबर से, नाम से नहीं। छह महीने बाद record[1] पढ़कर किसी को समझ नहीं आएगा कि यह तापमान है या नमी।
टपल दोनों का जवाब है: यह एक लिस्ट जैसा है, लेकिन बदला नहीं जा सकता — और इसके साथ एक सुविधा आती है, जिसका नाम अनपैकिंग है, जो इंडेक्स की जगह नाम इस्तेमाल करने देती है।
इस अध्याय के बाद आप यह कर पाएँगे
- टपल बनाना, और बताना कि कहाँ लिस्ट नहीं, टपल चाहिए
- अनपैकिंग से कई वैल्यू एक साथ कई नामों में रखना
- एक लाइन में दो वेरिएबल की वैल्यू आपस में बदलना
(5)और(5,)का फ़र्क़ पकड़ना- टपल पर
appendकरने परAttributeErrorक्यों आता है, यह बताना
पहले यह आना चाहिए: लिस्ट सॉर्ट करना और उसके मेथड।
टपल — ऐसी लिस्ट जो बदली नहीं जा सकती
स्क्वेयर ब्रैकेट की जगह सामान्य (गोल) ब्रैकेट:
point = (3, 7)
print(point)
print(point[0])
print(len(point))(3, 7)
3
2पढ़ना, इंडेक्स, len, स्लाइस, in, for से घूमना — लिस्ट में जो-जो करते थे, सब चलता है। फ़र्क़ एक ही है, और वही सब कुछ है:
point = (3, 7)
point[0] = 5TypeError: 'tuple' object does not support item assignmentमैसेज जाना-पहचाना लग रहा है? अध्याय 6 में स्ट्रिंग के अंदर का अक्षर बदलने पर ठीक यही मैसेज आया था, बस वहाँ 'str' लिखा था। Python में न बदलने वाली चीज़ें एक ही भाषा में शिकायत करती हैं।
बदलने वाले मेथड भी नहीं हैं:
point = (3, 7)
point.append(9)AttributeError: 'tuple' object has no attribute 'append'AttributeError का मतलब है "इस ऑब्जेक्ट में इस नाम का कुछ नहीं है"। टपल बदला नहीं जा सकता, इसलिए टपल में append नाम का कोई मेथड ही नहीं है। Python point.append ढूँढते-ढूँढते ही रुक जाता है, 9 जोड़ने की कोशिश तक पहुँचता ही नहीं। पिछले उदाहरण से फ़र्क़ यहाँ है: point[0] = 5 ऐसा काम माँग रहा था जो टपल करने नहीं देता, इसलिए TypeError; और यहाँ मेथड ही नहीं है, इसलिए AttributeError।
यह सुविधा क्यों है, रुकावट क्यों नहीं
पहले लगता है कि टपल कम ताक़त वाली लिस्ट है। उल्टा सोचिए: जो चीज़ बदलनी नहीं चाहिए, उसे ऐसे डिब्बे में रखें जो बदल नहीं सकता, तो ग़लती होने से पहले ही रुक जाती है।
किसी पॉइंट के निर्देशांक (3, 7) में तीसरा नंबर जोड़ने का कोई मतलब नहीं। एक तारीख़ (2026, 9, 16) में चौथी कोई चीज़ नहीं होनी चाहिए। ये चीज़ें टपल में रखें तो दुर्घटना तुरंत एरर बनकर पकड़ी जाती है, बाद में बग बनकर नहीं।
नियम के तौर पर: कितनी चीज़ें होंगी और उनका मतलब पहले से तय — टपल। कितनी होंगी पता नहीं, और सब एक ही टाइप की — लिस्ट।
इसलिए तीन दिन का मौसम लिस्ट के अंदर टपल है: कितने दिन होंगे पता नहीं (लिस्ट), लेकिन हर रिकॉर्ड में ठीक तीन चीज़ें (टपल)।
अनपैकिंग — असली फ़ायदा यहाँ है
point = (3, 7)
x, y = point
print(x)
print(y)3
7एक लाइन में दो नाम, दो वैल्यू। और अब point[1] नहीं, y — ऐसा नाम जो पढ़ते ही समझ आता है।
बाईं तरफ़ जितने नाम हैं, दाईं तरफ़ ठीक उतनी वैल्यू होनी चाहिए:
point = (3, 7)
x, y, z = pointValueError: not enough values to unpack (expected 3, got 2)यह मैसेज असामान्य रूप से मददगार है — कितनी उम्मीद थी और कितनी मिलीं, दोनों बता देता है।
अनपैकिंग सिर्फ़ टपल तक सीमित नहीं, लिस्ट में भी चलती है। लेकिन सबसे ज़्यादा काम टपल के साथ आती है, क्योंकि टपल में ही गिनती पहले से पता होती है।
अदला-बदली — एक लाइन में
दूसरी भाषाओं में दो वेरिएबल की वैल्यू आपस में बदलने के लिए एक अस्थायी तीसरा वेरिएबल लगता है। Python में नहीं लगता:
a = 1
b = 2
a, b = b, a
print(a, b)2 1यह लाइन कैसे काम करती है, यह समझना ज़रूरी है: Python पहले दाईं तरफ़ का पूरा हिसाब करता है, एक टपल (2, 1) बनाता है, फिर उसे बाईं तरफ़ अनपैक करता है। इसलिए a बदल जाने पर भी b की पुरानी वैल्यू तब तक पकड़ी जा चुकी होती है, और कुछ नहीं खोता।
ब्रैकेट असल में ज़रूरी नहीं
point = 3, 7
print(point)
print(type(point))(3, 7)
<class 'tuple'>टपल कॉमा बनाता है, ब्रैकेट नहीं। ब्रैकेट सिर्फ़ पढ़ने की सुविधा के लिए हैं। यह पता हो तो a, b = b, a वाली लाइन जादू नहीं लगती — दाईं तरफ़ b, a एक टपल ही है।
और यहीं से एक जाल आता है:
one = (5)
really = (5,)
print(type(one))
print(type(really))
print(len(really))<class 'int'>
<class 'tuple'>
1(5) कोई टपल नहीं — वह सिर्फ़ ब्रैकेट में लिपटा एक नंबर है, ठीक जैसे (2 + 3)। एक ही वैल्यू वाला टपल बनाना हो तो कॉमा ज़रूरी है: (5,)। देखने में टाइपो लगता है, लेकिन वही कॉमा पूरा फ़र्क़ है।
लूप में टपल
people = [("rafi", 22), ("ahmed", 35)]
for name, age in people:
print(f"{name} is {age}")rafi is 22
ahmed is 35for name, age in people हर टपल को सीधे दो नामों में अनपैक कर रहा है। person[0] और person[1] लिखने की ज़रूरत नहीं — और कोड पढ़ते ही समझ आता है कि कौन क्या है।
यह तरीक़ा आप पहले ही इस्तेमाल कर चुके हैं, बिना जाने:
stock = ["pen", "bag"]
for pair in enumerate(stock):
print(pair)(0, 'pen')
(1, 'bag')enumerate असल में टपल ही देता है। अध्याय 12 में for position, item in enumerate(...) लिखकर हम उन्हीं टपल को अनपैक कर रहे थे — तब इसका नाम ही नहीं जानते थे।
एक से दूसरे में बदलना
as_list = [3, 7]
as_tuple = (3, 7)
as_list.append(9)
print(as_list)
print(as_tuple)
print(list(as_tuple))
print(tuple(as_list))[3, 7, 9]
(3, 7)
[3, 7]
(3, 7, 9)list() और tuple() एक से दूसरा बनाते हैं — नई चीज़ बनाते हैं, पुरानी जैसी की तैसी रहती है। टपल को "बदलना" हो तो यही तरीक़ा है: लिस्ट बनाइए, बदलिए, फिर टपल बनाइए।
एक पूरा उदाहरण
weather.py:
# A tuple is the right shape for a record that must not change
readings = [
("monday", 31.5, 78),
("tuesday", 33.0, 71),
("wednesday", 29.5, 85),
]
print("Day Temp Humidity")
for day, temp, humidity in readings:
print(f"{day:<10} {temp:>5} {humidity:>5}")
hottest = readings[0]
for reading in readings:
if reading[1] > hottest[1]:
hottest = reading
day, temp, humidity = hottest
print()
print(f"Hottest was {day} at {temp}")
temps = []
for _, temp, _ in readings:
temps.append(temp)
print("Temps :", temps)
print("Average :", round(sum(temps) / len(temps), 2))Day Temp Humidity
monday 31.5 78
tuesday 33.0 71
wednesday 29.5 85
Hottest was tuesday at 33.0
Temps : [31.5, 33.0, 29.5]
Average : 31.33चार बातें ध्यान देने लायक़ हैं।
बाहर लिस्ट, अंदर टपल। दिनों की गिनती बढ़ सकती है, इसलिए बाहर वाली लिस्ट है। हर रिकॉर्ड में ठीक तीन चीज़ें हैं, इसलिए अंदर वाले टपल हैं। असली डेटा का सबसे आम आकार यही है।
f"{day:<10}" और f"{temp:>5}" — कॉलम सीधे रखने के लिए। < बाईं ओर सटाता है, > दाईं ओर, और नंबर बताता है कि कितनी जगह लेनी है। अध्याय 6 के :.2f की तरह, कोलन के बाद वाला हिस्सा सिर्फ़ फ़ॉर्मैटिंग है।
सबसे गरम दिन ढूँढने के लिए reading[1] लिखना पड़ा, क्योंकि तुलना के समय पूरा टपल हाथ में है, अनपैक किया हुआ नहीं। मिलते ही उसे तुरंत अनपैक कर दिया गया — इसलिए उसके बाद वाली लाइन में इंडेक्स नहीं है।
for _, temp, _ in readings — अंडरस्कोर एक आम रिवाज़ है, जिसका मतलब है "यह वैल्यू नहीं चाहिए"। Python के लिए यह बाक़ी नामों जैसा ही एक नाम है, लेकिन पढ़ते समय यह बता देता है कि कौन-सा हिस्सा जानबूझकर छोड़ा जा रहा है।
कुछ टूटी हुई हालतें और उनका हल
TypeError: 'tuple' object does not support item assignment टपल के अंदर की एक वैल्यू बदलने की कोशिश। टपल बदला नहीं जा सकता — या तो शुरू से लिस्ट इस्तेमाल कीजिए, या list(...) से बदलकर काम कीजिए।
AttributeError: 'tuple' object has no attribute 'append' वही वजह, दूसरे रूप में। append, remove, sort — बदलने वाला कोई मेथड टपल में नहीं है। लेकिन sorted(my_tuple) चलता है, क्योंकि वह एक नई लिस्ट लौटाता है, टपल को छूता नहीं।
ValueError: not enough values to unpack (expected 3, got 2) बाईं तरफ़ जितने नाम हैं, दाईं तरफ़ उतनी वैल्यू नहीं हैं। print(len(record)) से देख लीजिए कि अंदर असल में कितनी हैं।
ValueError: too many values to unpack (expected 2) उल्टी समस्या — वैल्यू ज़्यादा, नाम कम।
एक वैल्यू वाला टपल बनाया, लेकिन वह टपल नहीं बना कॉमा छूट गया। (5) एक नंबर है, (5,) एक टपल।
टपल के अंदर वाली लिस्ट बदल गई टपल अपना खुद का ढाँचा बचाता है — उसके अंदर कौन-सी चीज़ें हैं, यह नहीं बदला जा सकता। लेकिन उनमें से कोई चीज़ खुद बदलने लायक़ हो, जैसे एक लिस्ट, तो उसका अंदर का हिस्सा बदला जा सकता है। ([1, 2], 3) में पहली लिस्ट में append करना चलता है।
चरण 4 / 6 — अनुमान
अपनी समझ की जाँच करें
अनपैक करने के बाद क्या प्रिंट होगा?
point = (3, 7)
x, y = point
print(y, x)- A3 7
- B(3, 7)
- Cएक `ValueError`
- D7 3
एक टपल में append करने की कोशिश। कौन-सा एरर आएगा, और वही क्यों?
point = (3, 7)
point.append(9)- A`ValueError`
- Bकुछ नहीं होता, टपल वैसा ही रहता है
- C`AttributeError` — टपल बदला नहीं जा सकता, इसलिए बदलने वाले मेथड उसमें हैं ही नहीं
- D`TypeError` — टपल में `append` नहीं किया जा सकता
दोनों लाइनों में फ़र्क़ बस एक कॉमा का है। type() क्या बताएगा?
one = (5)
really = (5,)
print(type(one))
print(type(really))- A<class 'int'> <class 'int'>
- B<class 'tuple'> <class 'tuple'>
- C<class 'int'> <class 'tuple'>
- D<class 'tuple'> <class 'int'>
उत्तर देने के लिए अकाउंट आवश्यक है
अपने उत्तर जाँचने के लिए साइन इन करें
प्रश्न ऊपर दिए गए हैं, और मन में उत्तर सोचना ही मुख्य कार्य है। सही उत्तर, व्याख्या और तीन-स्तरीय संकेत देखने के लिए साइन इन करें।
आपकी बारी
contacts.py नाम की एक फ़ाइल लिखिए, जिसमें कम से कम पाँच लोगों की एक लिस्ट हो, और हर व्यक्ति एक टपल हो — नाम, उम्र और एक पसंदीदा विषय।
फिर:
for name, age, subject in contacts:से सबको सीधे कॉलम में प्रिंट कीजिए- सबसे ज़्यादा उम्र वाले व्यक्ति को ढूँढकर, अनपैक करके, एक वाक्य में प्रिंट कीजिए
- सिर्फ़ नामों की एक लिस्ट बनाइए, और
joinसे एक लाइन में प्रिंट कीजिए - औसत उम्र प्रिंट कीजिए
- दो वेरिएबल की वैल्यू एक लाइन में आपस में बदलकर दिखाइए
फिर जानबूझकर तीन बार तोड़िए, और हर मैसेज पढ़िए:
- किसी टपल के अंदर की उम्र बदलने की कोशिश कीजिए
- किसी टपल में
appendकरने की कोशिश कीजिए - तीन वैल्यू वाले टपल को दो नामों में अनपैक करने की कोशिश कीजिए
तीन अलग एरर के नाम आएँगे — TypeError, AttributeError, ValueError। कौन-सा क्यों आया, यह खुद को समझा सकें तो टपल आपकी पकड़ में आ गया।
चरण 6 / 6
चुनौती — अध्याय की क्विज़
सरल से कठिन — दस प्रश्न, अंतिम वाले जानबूझकर चुनौतीपूर्ण बनाए गए हैं।
क्विज़ देने के लिए साइन इन करें