কম্পিউটার টিউটোরিয়াল

পাইথন ডেটা স্ট্রাকচার (Data Structures)

ডেটা স্ট্রাকচার প্রোগ্রামিং-এ অত্যন্ত গুরুত্বপূর্ণ। এগুলো ডেটাকে সাজাতে, সংরক্ষণ করতে, এবং পরিচালনা করতে ব্যবহৃত হয় যাতে সেটি অ্যাক্সেস এবং মডিফাই (modify) করার জন্য দক্ষ হয়।

সাপ্তাহিক লন্ডری (laundry) করার কাল্পনিক করুন। আদর্শভাবে, আপনি মোজা, টি-শার্ট, ট্রাউজার, এবং ডেলিকেটস (delicates) আলাদা আলাদা ড্রোরে (drawers) রাখেন সকালে বের হওয়ার আগে সহজে অ্যাক্সেস করার জন্য। আপনি একটি ডেটা স্ট্রাকচার দিয়ে প্রস্তুত হচ্ছেন। এখন, কাল্পনিক করুন সেই সকল জিনিসপত্র বা तो একই একক ড্রোরে বা একাধিক ড্রোরে সংগঠন ছাড়া ফেলা হয়েছে। কাজের জন্য বা রাতে বের হওয়ার জন্য সাজানোর জন্য আপনাকে কতক্ষণ লাগবে বলে মনে করেন? এটি ডেটা স্ট্রাকচার ছাড়া প্রস্তুত হচ্ছে।

এই আর্টিকেলে, আমরা পাইথনের বিল্ট-ইন ডেটা স্ট্রাকচারগুলোতে গভীরে যাব।

পাইথনে বিল্ট-ইন ডেটা স্ট্রাকচার

পাইথনে বিল্ট-ইন ডেটা স্ট্রাকচারগুলো হলো লিস্ট (lists), ডিকশনারি (dictionaries), টাপল (tuples), এবং সেট (sets)।

লিস্ট (Lists)

লিস্ট হচ্ছে মিউটেবল (mutable - পরিবর্তন যোগ্য) ডেটা স্ট্রাকচার যেগুলো ভিন্ন উপাদান বা অংশ থাকতে পারে। অন্য কথায়, একটি একক লিস্ট বিভিন্ন ডেটা টাইপ ধারণ করতে পারে।

list = ['string', 300, (2, 4), 'that previous data type was a tuple']

লিস্ট ডেটা স্ট্রাকচারটির ১১টি মেথড আছে যা লিস্টে যোগ করতে, সরাতে, বা ম্যানিপুলেট (manipulate) করতে ব্যবহৃত হয়।

একটি লিস্টে উপাদান যোগ করা

  • append(): append() মেথড একটি একক আইটেম লিস্টে যোগ করে
list = ['string, next is tupel', (2, 1), 3]
list.append(500)
print(list) # prints ['string, next is tupel', (2, 1), 3, 500]
  • extend(): extend() মেথড লিস্টকে ইটারেবল (iterable) থেকে সকল আইটেম দিয়ে অ্যাপেন্ড (append) করে। এটি append() থেকে এইভাবে ভিন্ন।
list = ['string, next is tupel', (2, 1), 3]
list.append((8, 9))
print(list) # prints ['string, next is tupel', (2, 1), 3, (8, 9)]
# Notice that append() leave (8, 9) as a tuple
list = ['string, next is tupel', (2, 1), 3]
list.extend((8, 9))
print(list) # prints ['string, next is tupel', (2, 1), 3, 8, 9]
# Notice that extend() did not leave (8, 9) as a tuple
  • insert(): insert() মেথড একটি দেওয়া পজিশন বা সূচকে একটি আইটেম ইনসার্ট (insert) করে। প্রথম আর্গুমেন্ট হচ্ছে ইনসার্ট করা উপাদানের সূচক, দ্বিতীয় আর্গুমেন্ট হচ্ছে উপাদানটিই।
list = ['string, next is tupel', (2, 1), 3]
list.insert(0, 700)
print(list) # prints [700, 'string, next is tupel', (2, 1), 3]
# inserted 700 in the 0 index

একটি লিস্ট থেকে উপাদান সরানো

  • remove(): remove() মেথড লিস্টে প্রথম আইটেমটি সরিয়ে দেয় যেটি এটি দেওয়া মানের সমান।
list = ['string, next is tupel', (2, 1), 3, 8, 3]
list.remove(3)
print(list) # prints ['string, next is tupel', (2, 1), 8, 3]
  • pop(): pop() মেথড দিয়ে गये পজিশনে থাকা মানটি সরিয়ে দেয়, তবে যদি কোনো সূচক দিয়ে না থাকে, তবে এটি শেষ আইটেমটি সরিয়ে দেয়।
list = ['string, next is tupel', (2, 1), 3]
list.pop(0)
print(list) # prints [(2, 1), 3]
list = ['string, next is tupel', (2, 1), 3]
list.pop()
print(list) # prints ['string, next is tupel', (2, 1)]
  • clear(): clear() মেথড কোনো আর্গুমেন্ট নেয় না। এটি লিস্ট থেকে সকল আইটেম সরিয়ে দেয়।
list = ['string, next is tupel', (2, 1), 3]
list.clear()
print(list) # prints []

অন্যান্য লিস্ট মেথড

  • index(): index() মেথড দিয়ে गये মানের সূচক ফেরত দেয়।
list = [8, 20, 1, 9, 2, 3, 937, 0]
print(list.index(9)) # prints 3
  • count(): count() মেথড গণনা করে একটি মান লিস্টে কতবার আয়ত্ত হয়।
list = [8, 20, 1, 8, 2, 8, 937, 8]
print(list.count(8)) # prints 4
  • sort(): sort() মেথড আর্গুমেন্টের সাথে বা ছাড়া ব্যবহার করা যায় এবং কাস্টম সোর্টিং (custom sorting) এর জন্য ব্যবহার করা যায়।
list = [8, 20, 1, 9, 2, 3, 937, 0]
list.sort()
print(list) # prints [0, 1, 2, 3, 8, 9, 20, 937]
list = [8, 20, 1, 9, 2, 3, 937, 0]
list.sort(reverse=True)
print(list) # prints [937, 20, 9, 8, 3, 2, 1, 0]
  • reverse(): reverse মেথড লিস্টের উপাদানগুলোকে ইন-প্লেস (in-place) রিভার্স (reverse) করে, উপরের সোর্ট মেথডের মতো যা কাস্টম সোর্টিং আর্গুমেন্ট নেয়।
list = [8, 20, 1, 9, 2, 3, 937, 0]
list.reverse()
print(list) # prints [0, 937, 3, 2, 9, 1, 20, 8]
  • copy(): copy() মেথড শুধু একটি লিস্টের কপি ফেরত দেয়।
list = [8, 20, 1, 9, 2, 3, 937, 0]
list.copy()
print(list) # prints [8, 20, 1, 9, 2, 3, 937, 0]

টাপল (Tuples)

টাপল হচ্ছে প্যারেনথেসিস (parenthesis) এ ধারিত ডেটা। লিস্টের বিপরীতে, এগুলো মিউটেবল (mutable - পরিবর্তন যোগ্য) নয়, এবং এগুলো লিস্টের চেয়ে দ্রুত। কারণ এগুলো ইমিউটেবল (immutable), আমরা এগুলোকে ডিকশনারিতে কী হিসেবেও ব্যবহার করতে পারি। টাপলগুলো ফাংশন থেকে একাধিক ফলাফল ফেরত দেওয়ার জন্যও ব্যবহার করা যেতে পারে।

আমরা কনক্যাটেনেশন (concatenation) ব্যবহার করে একটি টাপলে ডেটা যোগ করতে পারি।

tuple = (1, 2, 3)
print(tuple) # prints (1, 2, 3)
tuple = tuple + (4, 5, 6)
print(tuple) # prints (1, 2, 3, 4, 5, 6)

ডিকশনারি (Dictionaries)

ডিকশনারি হচ্ছে ডেটা স্ট্রাকচার যেগুলো কী-ভ্যালু (key-value) জোড়া ধারণ করে জাভাস্ক্রিপ্টের অবজেক্টের (objects) মতো। লিস্টের মতো, এই ডেটা স্ট্রাকচারগুলো মিউটেবল, অর্থাৎ আমরা এর ডেটা পরিবর্তন করতে পারি।

একটি কী-ভ্যালু জোড়ার উদাহরণ হলো একজন ব্যক্তির বৈশিষ্ট্য এবং সেই বৈশিষ্ট্যগুলোর বর্ণনা। নাম, বয়স, উচ্চতা, এবং ওজন সব কী হতে পারে। জош (Josh), ৩৩, ৫'১০, ১৮০ lbs, সেগুলোর ভ্যালু হতে পারে।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}

কারণ ডিকশনারি মিউটেবল, আমরা 'Josh' কে অন্য একটি নাম দিয়ে পরিবর্তন করতে পারি।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict['name'] = 'Patrick'
print(dict) # prints {'name': 'Patrick', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}

আমরা নতুন কী-ভ্যালু জোড়া তৈরি করে ভ্যালু যোগ করতে পারি।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict['location'] = 'San Francisco'
print(dict) # prints {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs', 'location': 'San Francisco'}

আমরা ডিকশনারিতে কী-ভ্যালু জোড়াও ডিলিট (delete) করতে পারি del কীওয়ার্ড, pop(), বা popitem() মেথড ব্যবহার করে। নোট করুন যে ডিকশনারির সাথে pop() অবশ্যই একটি আর্গুমেন্ট নিতে হবে, তাই আমাদের ডিকশনারি থেকে শেষ কী-ভ্যালু জোড়া সরাতে popitem() ব্যবহার করতে হবে।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
del dict['name']
print(dict) # prints {'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict.pop('name')
print(dict) # prints {'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
dict.popitem()
print(dict) # prints {'name': 'Josh', 'age': 33, 'height': "5'10"}

আমরা ডিকশনারির শুধু কীগুলো বা শুধু ভ্যালুগুলোও প্রিন্ট করতে পারি।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
print(dict.keys()) # prints dict_keys(['name', 'age', 'height', 'weight'])
dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
print(dict.values()) # prints dict_values(['Josh', 33, "5'10", '180 lbs'])

কী-ভ্যালু জোড়া হিসেবে প্রিন্ট করতে, আমরা items() মেথড ব্যবহার করতে পারি।

dict = {'name': 'Josh', 'age': 33, 'height': "5'10", 'weight': '180 lbs'}
print(dict.items()) # prints dict_items([('name', 'Josh'), ('age', 33), ('height', "5'10"), ('weight', '180 lbs')])

সেট (Sets)

সেট হচ্ছে মিউটেবল, আনঅর্ডার্ড (unordered), ইউনিক (unique) উপাদানগুলোর সংকলন, অর্থাৎ এগুলোর ডুপ্লিকেট (duplicate) উপাদান নেই। সেট ডিকশনারির মতো কার্লি ব্রেসেস (curly brackets) এ ডেটা ধারণ করে, কিন্তু ডিকশনারির বিপরীতে, সেটের কী-ভ্যালু জোড়া নেই।

set = {1, 2, 2, 2, 3, 3, 4, 4}
print(set) # prints {1, 2, 3, 4}

আমরা add() মেথড ব্যবহার করে সেটে উপাদান যোগ করতে পারি।

set = {1, 2, 2, 2, 3, 3, 4, 4}
set.add(5)
print(set) # print {1, 2, 3, 4, 5}

সেট ব্যবহার করার সময় আমাদের চারটি অন্য মেথড উপলব্ধ: union(), intersection(), difference(), এবং symmetric_difference()।

  • union(): union() মেথড দুটি ভিন্ন সেটকে যুনিয়ন (unionize) করে, উভয়ের সাধারণ অংশগুলো নেয় এবং সেগুলোকে ডুপ্লিকেট ছাড়া একটি একক সেট হিসেবে তৈরি করে।
set = {1, 2, 2, 2, 3, 3, 4, 4}
set.add(5)
print(set) # prints {1, 2, 3, 4, 5}
anotherSet = {3, 3, 4, 4, 5, 5, 6}
print(set.union(anotherSet)) # prints {1, 2, 3, 4, 5, 6}
  • intersection(): intersection মেথড দুটি সেটের সাধারণ উপাদানগুলো খুঁজে বের করে।
set = {1, 2, 2, 2, 3, 3, 4, 4}
set.add(5)
print(set) # prints {1, 2, 3, 4, 5}
anotherSet = {3, 3, 4, 4, 5, 5, 6}
print(set.intersection(anotherSet)) # prints {3, 4, 5}
  • difference(): difference মেথড intersection মেথডের বিপরীতে কাজ করে בכך যে এটি সকল সাধারণ অংশ বাদ দিয়ে প্রথম সেট থেকে যা বাকি থাকে সেটি প্রিন্ট করে।
set = {1, 2, 2, 2, 3, 3, 4, 4}
set.add(5)
print(set) # prints {1, 2, 3, 4, 5}
anotherSet = {3, 3, 4, 4, 5, 5, 6}
print(set.difference(anotherSet)) # prints {1, 2}
  • symmetric_difference(): symmetric_difference() মেথড difference মেথডের মতো কিন্তু আউটপুটে দুটি সেটের পার্থক্য (difference) পাওয়া যায়।
set = {1, 2, 2, 2, 3, 3, 4, 4}
set.add(5)
print(set) # prints {1, 2, 3, 4, 5}
anotherSet = {3, 3, 4, 4, 5, 5, 6}
print(set.symmetric_difference(anotherSet)) # prints {1, 2, 6}
  1. পাইথনে খালি লিস্ট চেক করার সেরা পদ্ধতি

  2. পাইথনে ইমিউটেবল ডেটা স্ট্রাকচার বাস্তবায়ন কীভাবে করবেন?

  3. সি-এ Structures (স্ট্রাকচার)

  4. ডেটা স্ট্রাকচারে অ্যাডজেসেন্সি লিস্ট