Skip to content
This page has been auto-translated and may contain errors.View in English

सूचियाँ (Lists)

एक वेरिएबल एक चीज़ रखता है। एक सूची क्रम में कई चीज़ें रखती है, सभी एक ही नाम के तहत। एक लीडरबोर्ड स्कोर का एक रैंक किया गया क्रम है। एक क्विज़ प्रश्नों का संग्रह है। जब आपको संबंधित मूल्यों के समूह को प्रबंधित करने की आवश्यकता हो, तो आपको एक सूची की आवश्यकता होती है।

सूचियाँ Python की सामान्य-उद्देश्य वाली क्रमबद्ध, म्यूटेबल अनुक्रम हैं। ये किसी भी ऐसी चीज़ के लिए प्राकृतिक रूप से उपयुक्त हैं जो समय के साथ बदलती है: आइटम जोड़े या हटाए जाते हैं, क्रम बदला जाता है, सामग्री फ़िल्टर या सॉर्ट की जाती है। जब क्रम मायने रखता है और संग्रह बदलता है, तो सूची आमतौर पर सही पहली पसंद होती है।

list Python की डायनामिक ऐरे है: एक क्रमबद्ध, म्यूटेबल अनुक्रम जो एक सन्निहित हीप आवंटन द्वारा समर्थित है। रैंडम एक्सेस O(1) है। append() amortised O(1) है क्योंकि ऐरे ओवर-आवंटित करती है और ओवरफ्लो पर बढ़ती है। insert() और remove() O(n) हैं क्योंकि वे बाद के तत्वों को शिफ्ट करते हैं। इन लागतों को अन्य संरचनाओं को प्राथमिकता देने के निर्णयों का मार्गदर्शन करना चाहिए।

एक सूची बनाना

वर्गाकार कोष्ठक, कॉमा से अलग किए गए मान। सूचियाँ किसी भी प्रकार के मिश्रण को रख सकती हैं, और एक खाली सूची मान्य है और एक प्रारंभिक बिंदु के रूप में सामान्य है जिसे आप समय के साथ बनाते हैं।

सूचियाँ ब्रैकेट सिंटैक्स के साथ परिभाषित होती हैं और सम्मिलन क्रम को संरक्षित करती हैं। ये किसी भी Python मान को रख सकती हैं, जिसमें अन्य सूचियाँ भी शामिल हैं। खाली सूची [] मानक प्रारंभिक बिंदु है जब आप आइटमों को क्रमिक रूप से जमा करते हैं।

ब्रैकेट लिटरल कुछ पूर्व-आवंटित क्षमता के साथ हीप पर एक नया list ऑब्जेक्ट आवंटित करता है। तत्व कोई भी Python ऑब्जेक्ट हो सकते हैं; सूची सीधे मान नहीं, बल्कि संदर्भ संग्रहीत करती है। विषम तत्व प्रकार मान्य हैं लेकिन त्वरित स्क्रिप्ट के बाहर व्यवहार में असामान्य हैं।

python
scores   = [87, 92, 74, 65, 91]
players  = ["आर्यन", "प्रिया", "रोहन"]
mixed    = ["आर्यन", 87, True, 3.14]   # कोई भी प्रकार, हालांकि असामान्य
empty    = []

इंडेक्सिंग और स्लाइसिंग

सूचियाँ स्ट्रिंग्स के समान संख्या प्रणाली का उपयोग करती हैं: स्थितियाँ 0 से शुरू होती हैं, ऋणात्मक संख्याएँ अंत से गिनती हैं। आप अपनी स्थिति के अनुसार किसी भी आइटम को पढ़ते हैं। चूंकि सूचियाँ म्यूटेबल हैं, आप एक विशिष्ट स्थिति पर लिख भी सकते हैं।

सूची इंडेक्सिंग और स्लाइसिंग स्ट्रिंग्स के समान नियमों का पालन करती हैं। मुख्य अंतर म्यूटेबिलिटी है: आप किसी इंडेक्स या स्लाइस को असाइन करके आइटमों को जगह पर बदल सकते हैं, जो स्ट्रिंग्स की अनुमति नहीं देती।

list.__getitem__ पूर्णांकों और slice ऑब्जेक्ट्स को स्वीकार करता है, str के समान क्लैम्पिंग नियमों का पालन करता है। __setitem__ आइटम असाइनमेंट को सक्षम करता है। स्लाइस असाइनमेंट तत्वों की एक श्रृंखला को बदलता है और यदि प्रतिस्थापन की लंबाई अलग है तो सूची का आकार बदल सकता है: lst[1:3] = [10, 20, 30] दो आइटमों को तीन से बदलता है।

python
scores = [87, 92, 74, 65, 91]

scores[0]      # 87  (पहला)
scores[-1]     # 91  (अंतिम)
scores[1:3]    # [92, 74]
scores[:2]     # [87, 92]
scores[::-1]   # [91, 65, 74, 92, 87]  (उल्टा)

scores[0] = 90   # म्यूटेबल: काम करता है (स्ट्रिंग्स TypeError उठाएँगे)

आइटम जोड़ना

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

append() O(1) amortised है और एक सूची को आइटम दर आइटम बनाने का मानक तरीका है। insert() O(n) है क्योंकि यह बाद के तत्वों को शिफ्ट करता है। extend() += के बराबर है और एक लूप के अंदर बार-बार append() से अधिक कुशल है।

append() पूर्व-आवंटित बफर का उपयोग करता है और केवल तब कॉपी करता है जब ओवरफ्लो रिसाइज ट्रिगर करता है। पहले कुछ रिसाइज के बाद वृद्धि कारक लगभग 1.125x है, जो amortised O(1) देता है। insert(0, x) O(n) है: हर तत्व दाईं ओर शिफ्ट होता है। बार-बार सामने सम्मिलन के लिए, collections.deque O(1) appendleft प्रदान करता है। extend(iterable) __iter__ को एक बार कॉल करता है और एक ऑपरेशन में बढ़ता है।

python
scores = [87, 92, 74]

scores.append(65)          # [87, 92, 74, 65]
scores.insert(1, 100)      # [87, 100, 92, 74, 65]
scores.extend([55, 71])    # [87, 100, 92, 74, 65, 55, 71]

एक सामान्य गलती: सूची के साथ append() पूरी सूची को एक आइटम के रूप में जोड़ता है, जिससे आपको एक सूची के अंदर एक सूची मिलती है। मर्ज करने के लिए extend() का उपयोग करें:

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

append(x) list_append को x के साथ एक एकल ऑब्जेक्ट के रूप में कॉल करता है, चाहे उसका प्रकार कुछ भी हो। extend(iterable) तर्क पर __iter__ कॉल करता है और प्रत्येक तत्व को व्यक्तिगत रूप से जोड़ता है। += ऑपरेटर __iadd__ कॉल करता है, जो आंतरिक रूप से extend कॉल करता है।

python
scores.append([55, 71])    # [..., [55, 71]]  नेस्टेड सूची, शायद गलत
scores.extend([55, 71])    # [..., 55, 71]    मर्ज किया गया, सही

आइटम हटाना

आइटम हटाने के चार उपकरण। remove() मान द्वारा खोज करता है। pop() स्थिति द्वारा हटाता है और आपको आइटम वापस देता है। del स्थिति द्वारा बिना रिटर्न मान के हटाता है। clear() पूरी सूची खाली करता है।

remove() O(n) है: यह मान द्वारा पहली घटना के लिए स्कैन करता है। बिना तर्क के pop() अंतिम आइटम के लिए O(1) है। किसी भी अन्य स्थिति के लिए pop(i) O(n) है क्योंकि तत्व शिफ्ट होते हैं। del scores[i] pop(i) के बराबर है लेकिन रिटर्न मान को छोड़ देता है।

remove(value) प्रत्येक तत्व पर __eq__ कॉल करता है जब तक कि कोई मैच नहीं मिल जाता, फिर सभी बाद के तत्वों को बाईं ओर शिफ्ट करता है: O(n)। pop(-1) O(1) है, कोई शिफ्टिंग की आवश्यकता नहीं। किसी भी अन्य इंडेक्स के लिए pop(i) O(n) है। मनमानी स्थितियों से बार-बार हटाने के लिए, अपने डेटा को पुनर्संरचित करने या एक अलग संग्रह का उपयोग करने पर विचार करें।

python
scores = [87, 92, 74, 65, 91]

scores.remove(74)    # 74 की पहली घटना हटाता है
scores.pop()         # अंतिम आइटम हटाता और लौटाता है (91)
scores.pop(0)        # स्थिति 0 पर आइटम हटाता और लौटाता है (87)
del scores[1]        # स्थिति 1 पर हटाता है, कोई रिटर्न मान नहीं
scores.clear()       # सब कुछ हटा देता है

यदि मान सूची में नहीं है तो remove() ValueError उठाता है। यदि आप निश्चित नहीं हैं तो पहले in से जाँच करें:

python
if 74 in scores:
    scores.remove(74)

मिस पर remove() ValueError उठाता है। in जाँच एक अतिरिक्त O(n) स्कैन जोड़ती है; आप दो पास करते हैं। एकल-उपयोग कोड के लिए यह ठीक है। try/except ValueError के साथ उचित त्रुटि हैंडलिंग Files and exceptions अध्याय में शामिल है।

in + remove() पैटर्न दो O(n) स्कैन हैं। जब क्रम को संरक्षित करने की आवश्यकता नहीं हो, तो एक तेज़ तरीका है लक्ष्य को अंतिम तत्व के साथ स्वैप करना और पॉप करना: O(1)। O(1) लुकअप के साथ सेट सदस्यता के लिए, list के बजाय set का उपयोग करें, जो Tuples, sets अध्याय में शामिल है।

सॉर्टिंग

sorted() एक बिल्कुल नई सॉर्टेड सूची लौटाता है और आपके मूल को अछूता छोड़ देता है। .sort() सूची को जगह पर सॉर्ट करता है और None लौटाता है। यह अंतर जितना लगता है उससे अधिक मायने रखता है।

sorted() सुरक्षित डिफ़ॉल्ट है: यह कभी भी मूल को संशोधित नहीं करता। .sort() जगह पर संशोधित करता है और None लौटाता है, जो एक सामान्य जाल है। .sort() के परिणाम को असाइन करने पर आपको None मिलता है, सॉर्टेड सूची नहीं। जब आपको मूल बरकरार चाहिए तो sorted() का उपयोग करें; जब आप केवल सॉर्टेड संस्करण चाहते हैं तो .sort() का उपयोग करें।

दोनों Timsort का उपयोग करते हैं: एक हाइब्रिड मर्ज/इन्सर्शन सॉर्ट, सबसे खराब स्थिति में O(n log n) और लगभग सॉर्टेड डेटा पर O(n)। Timsort स्थिर है: समान तत्व अपने मूल सापेक्ष क्रम को संरक्षित करते हैं। .sort() जानबूझकर None लौटाता है (कमांड-क्वेरी सेपरेशन)। sorted() किसी भी iterable को स्वीकार करता है, केवल सूचियाँ नहीं, और हमेशा एक सूची लौटाता है।

python
scores = [87, 42, 96, 55, 71]

ranked = sorted(scores)            # [42, 55, 71, 87, 96] (नई सूची)
scores.sort()                      # जगह पर सॉर्ट, None लौटाता है
scores.sort(reverse=True)          # [96, 87, 71, 55, 42]

result = scores.sort()             # result None है, सॉर्टेड सूची नहीं

उपयोगी ऑपरेशन

Python में बिल्ट-इन टूल्स का एक सेट है जो सीधे सूचियों पर काम करते हैं। len(), sum(), min(), और max() वे चार हैं जिनका आप लगातार उपयोग करेंगे।

बिल्ट-इन अनुक्रम फ़ंक्शन किसी भी सूची पर काम करते हैं। in सूचियों के लिए एक रैखिक स्कैन है; यदि आपको तेज़ बार-बार सदस्यता परीक्षण की आवश्यकता है, तो सेट में बदलें। यदि मान नहीं मिलता है तो .index() ValueError उठाता है।

len(), sum(), min(), max() सभी __iter__ कॉल करते हैं और किसी भी iterable पर काम करते हैं, केवल सूचियों पर नहीं। in सूचियों के लिए O(n) है; O(1) लुकअप के लिए, set का उपयोग करें। .index(value) भी O(n) है। sum() डिफ़ॉल्ट रूप से start=0 है और स्ट्रिंग कॉन्कैटनेशन का समर्थन नहीं करता; स्ट्रिंग्स के लिए "".join() का उपयोग करें।

python
scores = [87, 92, 74, 65, 91]

len(scores)          # 5
sum(scores)          # 409
min(scores)          # 65
max(scores)          # 92
scores.count(87)     # 1
scores.index(74)     # 2
74 in scores         # True
74 not in scores     # False
scores.copy()        # शैलो कॉपी
scores.reverse()     # जगह पर उल्टा करता है

इटरेट करना

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

for item in list सूची के इटरेटर को आह्वान करता है और प्रत्येक चरण पर इसे आगे बढ़ाता है। enumerate(iterable, start=0) इटरेटर को रैप करता है और (index, value) जोड़े उत्पन्न करता है। काउंटर वेरिएबल बनाए रखने की तुलना में enumerate() का उपयोग करना साफ-सुथरा और कम त्रुटि-प्रवण है।

for list_iterator प्राप्त करने के लिए iter(list) आह्वान करता है, फिर StopIteration तक उस पर next() कॉल करता है। enumerate() किसी भी इटरेटर को रैप करता है और (i, value) जोड़े उत्पन्न करता है। start पैरामीटर काउंटर को ऑफसेट करता है लेकिन अंतर्निहित इंडेक्स को प्रभावित नहीं करता। i, item = pair अनपैक करना काम करता है क्योंकि enumerate ट्यूपल्स उत्पन्न करता है।

python
players = ["आर्यन", "प्रिया", "रोहन"]

for player in players:
    print(player)

for i, player in enumerate(players, start=1):
    print(f"{i}. {player}")
# 1. आर्यन
# 2. प्रिया
# 3. रोहन

for लूप्स और enumerate

for और enumerate() को Control flow अध्याय में पूरी तरह से शामिल किया गया है। संक्षिप्त संस्करण: for player in players प्रति आइटम एक बार चलता है; enumerate() आपको प्रत्येक इटरेशन पर स्थिति और मान दोनों देता है।

नेस्टेड सूचियाँ

एक सूची में अन्य सूचियाँ हो सकती हैं। यह है कि आप एक ग्रिड या तालिका का प्रतिनिधित्व कैसे करते हैं: पंक्तियों की एक सूची, प्रत्येक पंक्ति मानों की एक सूची है। वर्गाकार कोष्ठक के दो सेट एक आइटम तक पहुँचते हैं: पहला पंक्ति चुनता है, दूसरा कॉलम चुनता है।

नेस्टेड सूचियाँ सूची संदर्भों की सूचियाँ हैं। प्रत्येक आंतरिक सूची एक स्वतंत्र ऑब्जेक्ट है। चेन्ड सबस्क्रिप्ट्स के साथ एक्सेस करें: grid[row][col]। एक आंतरिक सूची को म्यूटेट करना बाहरी सूची को प्रभावित करता है क्योंकि बाहरी सूची उसी ऑब्जेक्ट का संदर्भ रखती है।

नेस्टेड सूचियाँ एक सच्ची 2D ऐरे नहीं हैं: बाहरी सूची ऑब्जेक्ट संदर्भ रखती है, और आंतरिक सूचियाँ अलग-अलग लंबाई और प्रकार की हो सकती हैं। एक्सेस दो __getitem__ कॉलों को चेन करता है। नेस्टेड सूची की शैलो कॉपी बाहरी कंटेनर को कॉपी करती है लेकिन आंतरिक सूचियों को नहीं; आंतरिक सूचियों में संशोधन दोनों कॉपियों को प्रभावित करते हैं।

python
grid = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

grid[0]       # [1, 2, 3]
grid[1][2]    # 6  (पंक्ति 1, कॉलम 2)

म्यूटेबिलिटी: समस्या

यह लगभग सभी को आश्चर्यचकित करता है। एक सूची को एक नए वेरिएबल को असाइन करना कॉपी नहीं बनाता। दोनों नाम एक ही सूची की ओर इशारा करते हैं। एक को बदलें और आप दूसरे को बदल देते हैं। एक स्वतंत्र कॉपी पाने के लिए, आपको स्पष्ट रूप से एक के लिए पूछना होगा।

सूची असाइनमेंट संदर्भ को कॉपी करता है, ऑब्जेक्ट को नहीं। दोनों नाम एक ही अंतर्निहित सूची की ओर इशारा करते हैं। किसी भी नाम के माध्यम से म्यूटेशन एक ही डेटा को प्रभावित करते हैं। जब आपको स्वतंत्र डेटा की आवश्यकता हो, तो .copy(), list(), या एक पूर्ण स्लाइस [:] के साथ स्पष्ट रूप से कॉपी करें।

b = a एक दूसरे नाम को उसी सूची ऑब्जेक्ट से बांधता है। b के माध्यम से कोई भी म्यूटेशन उस ऑब्जेक्ट को म्यूटेट करता है जिसकी ओर a भी इशारा कर रहा है। .copy() और a[:] एक शैलो कॉपी बनाते हैं: समान तत्व संदर्भों के साथ एक नया सूची ऑब्जेक्ट। अपरिवर्तनीय मानों की समतल सूचियों के लिए यह सुरक्षित है; नेस्टेड सूचियों के लिए, आंतरिक ऑब्जेक्ट अभी भी साझा किए जाते हैं।

python
a = [1, 2, 3]
b = a            # b एक कॉपी नहीं है; यह उसी सूची की ओर इशारा करता है

b.append(4)
print(a)         # [1, 2, 3, 4]  (बदला गया: a और b एक ही सूची हैं)
python
b = a.copy()    # स्वतंत्र कॉपी
b = list(a)     # समान परिणाम
b = a[:]        # यह भी समान है

# नेस्टेड सूचियाँ अभी भी अपने आंतरिक ऑब्जेक्ट साझा करती हैं:
matrix = [[1, 2], [3, 4]]
copy   = matrix.copy()

copy[0].append(99)
print(matrix)   # [[1, 2, 99], [3, 4]]  (आंतरिक सूची साझा थी)

नेस्टेड संरचनाओं के लिए जहाँ आपको पूर्ण स्वतंत्रता की आवश्यकता हो, प्रत्येक आंतरिक सूची को मैन्युअल रूप से कॉपी करें, या स्टैंडर्ड लाइब्रेरी से copy.deepcopy() का उपयोग करें, जो Modules अध्याय में शामिल है।

अधिक मेथड्स

Methodयह क्या करता है
.append(item)अंत में जोड़ें
.insert(i, item)स्थिति i पर सम्मिलित करें
.extend(iterable)एक iterable से सभी आइटम जोड़ें
.remove(value)मान की पहली घटना हटाएँ
.pop(i)स्थिति i पर आइटम हटाएँ और लौटाएँ (डिफ़ॉल्ट: अंतिम)
.clear()सभी आइटम हटाएँ
.index(value)पहली घटना की स्थिति
.count(value)घटनाओं की संख्या
.sort()जगह पर सॉर्ट करें
.reverse()जगह पर उल्टा करें
.copy()एक शैलो कॉपी लौटाएँ

व्यावहारिक रूप से

एक स्कोर ट्रैकर बनाना: परिणाम जोड़ें, उन्हें सॉर्ट करें, और एक सारांश प्रिंट करें।

python
scores = []

scores.append(87)
scores.append(54)
scores.append(92)
scores.append(67)
scores.append(45)

scores.sort(reverse=True)

print(f"रैंक किए गए स्कोर: {scores}")
print(f"उच्चतम: {scores[0]}")
print(f"न्यूनतम:  {scores[-1]}")
print(f"औसत: {sum(scores) / len(scores):.1f}")
print(f"टॉप 3:   {scores[:3]}")

नामों और स्कोर की दो समानांतर सूचियाँ: शीर्ष प्रदर्शनकर्ता खोजें और रैंक किए गए परिणाम प्रिंट करें।

python
names  = ["आर्यन", "प्रिया", "रोहन", "नेहा"]
scores = [87, 74, 92, 55]

best_score  = max(scores)
best_index  = scores.index(best_score)
best_player = names[best_index]

print(f"शीर्ष खिलाड़ी: {best_player} ({best_score})")
print(f"औसत:    {sum(scores) / len(scores):.1f}")

ranked = sorted(scores, reverse=True)
print(f"वितरण (रैंक किया गया): {ranked}")

for i in range(len(ranked)):
    print(f"  रैंक {i + 1}: {ranked[i]}")

एलियासिंग और कॉपी करने के बीच, और नेस्टेड सूचियों की शैलो और डीप कॉपी के बीच अंतर का प्रदर्शन।

python
# एलियासिंग: b एक कॉपी नहीं है
a = [1, 2, 3]
b = a
b.append(4)
print(a)    # [1, 2, 3, 4]  (समान ऑब्जेक्ट)

# शैलो कॉपी: बाहरी सूची स्वतंत्र है, आंतरिक सूचियाँ साझा हैं
matrix    = [[1, 2, 3], [4, 5, 6]]
shallow   = matrix.copy()
shallow[0].append(99)
print(matrix)    # [[1, 2, 3, 99], [4, 5, 6]]  (आंतरिक सूची साझा)

# एक for लूप के साथ मैन्युअल डीप कॉपी (कोई इम्पोर्ट आवश्यक नहीं)
matrix    = [[1, 2, 3], [4, 5, 6]]
deep_copy = []
for row in matrix:
    deep_copy.append(row[:])    # प्रत्येक आंतरिक सूची को स्पष्ट रूप से कॉपी करें

deep_copy[0].append(99)
print(matrix)    # [[1, 2, 3], [4, 5, 6]]  (अपरिवर्तित)