ডেটা টাইপ
কোন ডেটার ধরন নির্ণয় করার জন্য প্রোগ্রামিং এ বিভিন্ন ডেটা টাইপ নির্ধারণ করা হয় থাকে। পাইথনে ও এমন কয়েক ধরনের ডেটা টাইপ্স আছে ।
A. জেনারেল টাইপ
১।ইন্টিগ্রাল
পাইথনে দু’ধরনের বিল্ট-ইন ইন্টিগ্রাল ডেটা টাইপ্স আছে। int(Integer) এবং bool(Boolean) এরা প্রত্যেকেই ইমিউটেবল।
ক। ইন্টিজার
ইন্টিজার বা নাম্বার ডেটা টাইপ যেকোন ধরনের পূর্ণসংখ্যা। ইন্টিজার ভ্যালু কনভার্সনের জন্য পাইথনে কিছু বিল্ট-ইন ফাংশন আছে।
bin(x) – যে কোন সংখ্যা কে বাইনারি তে কনভার্ট করে hex(x) – যে কোন ইন্টিজার কে হেক্সা ডেসিমালে তে কনভার্ট করে int(x) – যে কোন ইন্টিজার কে ইন্টিজারে তে কনভার্ট করে oct(x) – যে কোন ইন্টিজার কে অক্টালে তে কনভার্ট করে pow(x,y) – x to the power y pow(x,y,z) – (x to the power y) % z
এছাড়াও আরও অনেক ফাংশন আছে, পাইথনের ডকুমেন্টেশন থেকে সেসবের ব্যবহার দেখে নিতে পার। মজার বিষয় হল এসব ফাংশন ছাড়া ও পাইথন ইন্টারপ্রেটারে আমরা ইন্টিজারের পাশাপাশি বাইনারি,অক্টাল ও হেক্সাডেসিমাল সংখ্যা ও লিখতে পারি...
>>> 15 #integer
15
>>> 0b101010 #binary
42
>>> 0o172356 #octal
62702
>>> 0xABCD #hexa-decimal
43981
এখানে লক্ষণীয় যে বাইনারি বুঝানোর জন্য 0b, অক্টাল বুঝানোর জন্য 0o এবং হেক্সাডসিমাল বুঝানোর জন্য 0x হেডিং ব্যবহার করতে হয়।
খ। বুলিয়ান
বুলিয়ান ডেটা টাইপ কোন এক্সপ্রেশনে সত্যতা যাচাই করে। বুলিয়ান ডেটা টাইপের দুটো ভ্যালু আছে True এবং False । True এর মান 1 এবং False এর মান 0. এবং একটি ইন্টিজার/ফ্লোট টাইপের ডেটার সাথে অপারেশন যোগ্য।
>>> a = True
>>> type(a)
<class 'bool'>
>>> 2 == 2
True
>>> 5<7
True
>>> 5>5
False
>>> 5+True
6
>>> 1.2 + True
2.2
>>> 7*False
0
>>> (5<7) == True
True
>>> 8 < 9 == True
False
শেষের কন্ডিশন টা কেন False হলো তা খুঁজে বের করা চেষ্টা করবে।
২। ফ্লোটিং
দশমিক সংখ্যাকে ফ্লোটিং নাম্বার বলে। পাইথনে তিন রকমের ফ্লোটিং পয়েন্ট নাম্বার আছে, বিল্ট-ইন float এবং complex. এবং অন্যটি পাইথন স্ট্যান্ডার্ড লাইব্রেরির decimal.Decimal টাইপ।
ক। ফ্লোটিং পয়েন্ট
কোন দশমিক সংখ্যাকে বোঝানোর জন্য ফ্লোট ডেটা টাইপের ব্যবহার করা হয়। সাইন্টেফিক E নোটেশন বোঝানোর জন্য e বা E ব্যবহার করা যায়।
>>> type(a)
<class 'float'>
>>> float(4)
4.0
>>> .4e9
400000000.0
>>> .5e2
50.0
>>> 4.4e2
440.0
>>> 2.e0
2.0
>>> 2.e1
20.0
>>> 2.e
SyntaxError: invalid syntax
>>> 2e
SyntaxError: invalid syntax
খ। কমপ্লেক্স
কমপ্লেক্স নাম্বার একটি ইমিউটেবল ডেটা টাইপ। কমপ্লেক্স নাম্বারের দুটো ভাগ থাকে, বাস্তব সংখ্যা (real) ও কাল্পনিক সংখ্যা(imaginary).
>>> 3 + 2j
(3+2j)
>>> type(3+2j)
<class 'complex'>
>>> a = 2.3 - 5.8j
>>> a.real
2.3
>>> a.imag
5.8
>>> a + 4j
(2.3+9.8j)
কমপ্লেক্স নাম্বারের একটি ফাংশন হচ্ছে conjugate() যা ইমাজিনারি অংশের চিহ্ন পরিবর্তন করে।
>>> a.conjugate()
(2.3-5.8j)
গ। ডেসিমাল
ডেসিমাল ডেটা টাইপ পাইথনের কোন বিল্ট ইন ডেটা টাইপ না। এটি পাইথন স্ট্যান্ডার্ড লাইব্রেরি থেকে ইম্পোর্ট করতে হয়। মূলত গানিতিক হিসেবে সূক্ষাতিসূক্ষ্য ভুল এড়ানোর জন্য এ ডেটা টাইপ ব্যবহার করা হয়।
>>> from decimal import *
>>> a = Decimal(3.4)
>>> a
Decimal('3.399999999999999911182158029987476766109466552734375')
3.4 এর প্রকৃত মান হচ্ছে ডেসিমাল ভ্যালুটি। এ সংখ্যাটিকে নির্দিষ্ট অংক পর্যন্ত আউট পুট পেতে quantize () ফাংশন ব্যবহার করতে হবে।
>>> a.quantize(Decimal('0.00'))
Decimal('3.40')
>>> from decimal import *
>>> Decimal(3.4) + Decimal(4.3)
Decimal('7.699999999999999733546474090')
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])
এখানে ডেসিমাল ডেটা টাইপ একটি বিশাল সংখ্যা রিটার্ণ করেছে। কিন্তু সবসময় এত বড় সংখ্যার প্রয়োজন হয় না । getcontext() ফাংশনের prec প্যারামিটার ব্যবহার করে আমরা নিজের ইচ্ছে মত সংখ্যা নির্ধারণ করে দিতে পারি। তবে এক্ষেত্রে দশমিকের আগের সংখ্যা ও prec এর ভ্যালু’র ভেতরে গণনা করা হয়।
>>> getcontext().prec = 5
>>> Decimal(3.4) + Decimal(4.3)
Decimal('7.7000')
>>> getcontext()
Context(prec=5, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])
লক্ষ্য কর getcontext() ফাংশনের prec প্যারামিটারের মান পরিবর্তন হয়ে গেছে।
৩। স্ট্রিংস
পাইথনে তিন নিয়মে স্ট্রিং তৈরি করা যায়। সিঙ্গেল,ডাবল অথবা ট্রিপল কোট ব্যবহার করে স্ট্রিং লিখা যায়৷
>>> my_string = 'Hello World'
>>> my_string_two = "Welcome to Python"
>>>my_string_three = '''I am writing a multiple line string'''
মাল্টিপল লাইন স্ট্রিং লিখতে আমরা চাইলে তিনটি ডাবল কোট ও ব্যবহার করতে পারি।
>>> my_string_four = """ String using
three double quotes """
আমরা যদি চাই স্ট্রিং এর ভিতরেই সিঙ্গেল/ ডাবল কোট ব্যবহার করব তাহলে আমরা পুরো স্ট্রিং টি সিঙ্গেল কোটে লিখলে ভেতরে ডাবল কোট ব্যবহার করব এবং পুরো স্ট্রিং টি ডাবল কোটে লিখলে ভিতরে সিঙ্গেল কোট ব্যবহার করব।
>>> my_string = 'My name is"Ratul" ’
>>>my_string = "My name is 'Ratul' "
অথবা আমরা চাইলে ট্রিপল কোট ও ব্যবহার করতে পারি।
স্ট্রিং কনকেটেনেশন(Concatenation)
পাইথনে একাধিক স্ট্রিং কে যোগ করাকে স্ট্রিং কনকেটেনেটিং বলে। এর জন্য আমরা ' + ' অপারেটর ব্যবহার করি।
>>>name = "Tommy is my dog."
>>>color = "His color is Black"
>>>my_string = name + color
>>>my_string
Tommy is my dog. His color is Black
স্ট্রিং মেথডস
স্ট্রিং হচ্ছে এক ধরনের অবজেক্ট। পাইথনে স্ট্রিং এর জন্য কিছু বিল্ট ইন মেথড/ ফাংশন আছে। যেমন আমরা যদি স্ট্রিং কে সম্পূর্ণ আপার/লোয়ার কেজ এ রূপান্তর করতে চাই তাহলে আমরা পাইথনে upper() বা lower() মেথড ব্যবহার করতে পারি।
আবার যদি শুধু মাত্র প্রথম অক্ষর ক্যাপিটালাইজ করতে চাই তখন আমরা capitalize() ফাংশন ব্যবহার করি। স্ট্রিং এর খুবই গুরুত্বপূর্ণ দুটি মেথড হলঃ
split() ও join()
split() ফাংশন কোন স্ট্রিং এর প্রতিটি হোয়াইট স্পেস পর পর অংশকে একটি করে এলিমেন্ট হিসেবে নিয়ে লিস্টে ইনপুট করে। join() একটি স্ট্রিং মেথড যা আর্গুমেন্ট হিসবে একটি মাত্র ইটারেবল অবজেক্ট নেয় এবং একটি স্ট্রিং ক্লাসের অবজেক্ট রিটার্ন করে। এটি split() ফাংশনের বিপরীত কাজ করে।
>>>a = ['Programmers','are',"today's","Saints"]
>>>string = " ".join(a)
>>>string
Programmers are today's Saints
>>>string.split()
['Programmers','are',"today's",’Saints’]
>>> string = "-".join(a)
["Programmers-are-today's-Saints"]
এছাড়াও আরও কিছু স্ট্রিং ফাংশন হল...
>>> string = 'hunt Python'
>>> len(string)
11
>>> string.capitalize()
'Hunt python'
>>>
>>> string.upper()
'HUNT PYTHON'
>>>
>>> string.lower()
'hunt python'
>>>
>>> string = 'HuNt PyThOn'
>>> string.swapcase()
'hUnT pYtHoN'
>>>
>>> string = ' a b c '
>>> string
' a b c '
>>> string.strip()
'a b c'
পাইথনে অনেক স্ট্রিং মেথড আছে। সব গুলো মেথড দেখতে হলে ইন্টারপ্রেটারে dir(my_string) কমান্ড টাইপ করলেই হবে৷
স্ট্রিং স্লাইসিং
রিয়েল ওয়ার্ল্ড প্রবলেমের ক্ষেত্রে স্ট্রিং স্লাইসিং অনেক বেশি ব্যবহৃত হয়। স্লাইসিং করে স্ট্রিং এর প্রত্যেকটা ক্যারেক্টর একসেস করা যায়।
>>> my_string = "I like Python!"
যেহেতু পাইথন জিরো বেজড্ বা জিরো থেকে কাউন্টিং শুরু করে আমরা প্রথম এলিমেন্ট কে জিরো থেকেই কাউন্ট করব।
I [space] l i k e [space] p y t h o n !
0 1 2 3 4 5 6 7 8 9 10 11 12 13
>>>my_string [0:1]
'I'
>>>my_string [0:11]
'I like Pyth'
>>>my_string [0:14]
'I like Python!'
>>>my_string [2:14]
'like Python'
>>>my_string [ : ]
'I like Python’
(এখানে লক্ষণীয় যে আমরা ম্যাক্সিমাম লিমিট যত দিচ্ছি পাইথন ঠিক তার আগের সংখ্যা পর্যন্ত কাউন্ট করছে)
স্ট্রিং ফরম্যাটিং “স্ট্রিং ফরম্যাটিং” অর্থ হচ্ছে স্ট্রিং কে সুবিন্যস্ত বা গুছিয়ে লিখা। একটা বেজ স্ট্রিং এ অন্য একটি স্ট্রিং/ ইন্টিজার/ ফ্লোট ভ্যালু ইনসার্ট করা।ধরুন আমার ৫ টি আপেল আছে, এখন আমি সেটাকে প্রোগ্রামিং এ কিভাবে লিখব? my_apples = 5 এবং আমি চাই স্ক্রিনে প্রিন্ট করুক “Ratul has 5 apples”
এখন এই 5 তো ইন্টিজার ভ্যারিয়েবল,যখন আমি ইউজার থেকে একেক বার একেক ডেটা ইনপুট নিব তখন কিভাবে দেখাব? ৫ না হয়ে যদি ১০ হয় কিংবা আমার নামের জায়গায় যদি আপনার নাম হয়? তখন? বার বার তো আর কোড পরিবর্তন করা যাবে না… এই ধরনের সমস্যা এড়ানোর জন্যই মূলত স্ট্রিং ফরম্যাটিং ব্যবহার করা হয়… পাইথনে অনেক ভাবেই স্ট্রিং কে ফরম্যাট করা যায়। সবচেয়ে বেসিক-পুরোনো যে পদ্ধতি সেটা অনেকটা-ই ‘সি’র মতঃ
name = “Ratul”
apples_num = 5
print(“ %s has %i apples” %(name, apples_num))
আউটপুটঃ Ratul has 5 apples.
এখানে খেয়াল কর যে আমরা যতগুলো স্ট্রিং ইনপুট দিচ্ছি ততগুলো %s ব্যবহার করছি। কিন্তু আমরা যদি সমান সংখ্যক ইনপুট না দেই তাহলে আমাদের কি এরর দেখাবে?
print(“ %s has %i apples” %(name))
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
TypeError; not enough arguments for formattig string
এছাড়াও এই পদ্ধতির একটা সমস্যা হচ্ছে আমাদের আলাদা ডেটা টাইপের জন্য আলাদা আলাদা সিনট্যাক্স ব্যবহার করতে হয়…
সিঙ্গেল ক্যারেক্টারে জন্য %c স্ট্রিং এর জন্য %s ইন্টিজারের জন্য %i এরকম আরো অনেকগুলো আছে, তো এভাবে মনে রাখা কষ্টসাধ্য, কিন্তু পাইথনের কাজই হচ্ছে ব্যাপার গুলো সহজ থেকে সহজতর করা। সে কাজটি করে .format() মেথড… এর মাধ্যমে একটি স্ট্রিং এর মধ্যে থাকা কিছু আর্গুমেন্টকে রিপ্লেস বা সাবস্টিটিউট করা যায়।
>>>name = “Ratul”
>>>apples_num= 5
>>>final_string = “{} has {} apples” .format(name, apples_num)
>>>print(final_string)
Ratul has 5 apples
সহজ করে বলি, আমরা final_string ভ্যারিয়েবলটির ভেতর {} কার্লিব্রেসি (দ্বিতীয় বন্ধনী) দিয়ে কিছু শূন্যস্থান তৈরি করে করেছি, এরপর এর শেষে ফরম্যাট ফাংশনের ভেতর বলে দিয়েছি যে কোন শুন্যস্থান টাকে কোন ভ্যারিয়েবলের মান দিয়ে পূরণ করতে হবে। সেটা কিভাবে হল? আমরা যখন একের পর এক শূণ্যস্থান তৈরি করি পাইথন তখন এদেরকে বাই- ডিফল্ট ইন্ডেক্সিং করে(০ থেকে শুরু) । তার মানে আমাদের প্রথম শূন্যস্থানের ইন্ডেক্স ভ্যালু হচ্ছে ০, দ্বিতীয় শূন্যস্থানের ইন্ডেক্স ভ্যালু হচ্ছে ১… আগের প্রোগ্রামটা-ই যদি একটু অন্যভাবে রান করি তাহলে দেখো কি হয়।
>>>name = “Ratul”
>>>apples_num= 5
>>>final_string = “{0} has {1} apples”.format(name,apples_num)
>>>print(final_string)
Ratul has 5 apples
এইবার ও আউটপুট আগের মতই আসবে। এবার আমরা শূন্যস্থানে বলে দিয়েছি কোথায় ফরম্যাট ফাংশনের কোন আর্গুমেন্টের ভ্যালু বসবে মানে এই ইন্ডেক্স এর মান হচ্ছে ফরম্যাট ফাংশনের ইন্ডেক্স এর মান। চল কোডেই বোঝা যাক…
>>>name = “Ratul”
>>>apples_num= 5
>>>final_string = “{0} has {0} apples”.format(name,apples_num)
>>>print(final_string)
এর আউটপুট আসবে… Ratul has Ratul apples
ফরম্যাটিংয়ের সময় ইন্ডেক্সগুলো 0, 1, 2…. এইভাবে সিরিয়ালি দিতে হবে ব্যাপারটা কিন্তু এমন না। ইচ্ছে করলেই এগুলো আগে পরে কিংবা একাধিকবার করেও দেয়া যায়।
>>>name = “Ratul”
>>>apples_num= 5
>>>final_string = “{1} has {0} apples and {0} oranges“.format(apples_num,name)
>>>print(final_string)
এর আউটপুট আসবে… Ratul has 5 apples and 5 oranges
কিন্তু এই শেষ ও শেষ না। পাইথন ৩.৬ এ পাইথন একটি নতুন স্ট্রিং ফরম্যাটিং লিটারেল নিয়ে আসে। যা “এফ-স্ট্রিংস ফরম্যাটিং” বা “ স্ট্রিং ইন্টারপোলেশন” নামে ও পরিচিত। এবার আমরা শুধু নরমাল স্ট্রিং লিখে যেখানে প্রয়োজন সেখানে {} এর ভেতর ভ্যারিয়েবলের নাম বসিয়ে দিলেই কাজ হয়ে যাবে।
>>>name = “Ratul”
>>>apples_num= 5
>>>print( f”{name} has {apples_num} apples”)
এবার ও ঠিক এই আউটপুট টাই পাব। Ratul has 5 apples
ফরম্যাটিং এক্সপ্রেশন্সঃ
B. কালেকশন ডেটা টাইপ
আমরা যে ডেটা টাইপ্স গুলো নিয়ে আলোচনা করছি সেগুলো সিঙ্গেল ভ্যালু ডেটা নিতে পারত। কিন্তু আমরা যদি একটি ভ্যারিয়েবলে একই টাইপের বা ভিন্ন টাইপের ডেটা রাখতে চাই তখন আমাদের এক স্পেশাল ডেটা টাইপ প্রয়োজন হবে। এগুলো কে কালেকশন ডেটা টাইপ্স বলে। সি বা সি++ এ যেমন অ্যারে। এগুলোকে আবার ডেটা স্ট্রাকচার ও বলা হয়। কিন্তু পাইথনে এদের কে ডেটা টাইপ হিসেবেই ধরা হয়। যে নামেই ডাকি না কেন জিনিস তো একটাই।
১। সিকোয়েন্স টাইপ
এই ধরনের ডেটা টাইপে একই বা ভিন্ন ধরনের ডেটা কমা দিয়ে আলাদা করে রাখা হয়। একের পর এক ডেটা রেখে এই ডেটা টাইপ গুলো সাজানো থাকে বলে এদের সিকোয়েন্সিয়াল ডেটা টাইপ বলে।
ক. লিস্ট
লিস্ট হচ্ছে পাইথনের এক ধরনের ডেটা টাইপ যা এক সাথে একাধিক টাইপের ডেটা স্টোর করতে পারে। পাইথনে লিস্ট লিখতে স্কয়ার ব্রাকেট "[ ]" ব্যবহার করা হয় এবং এলিমেন্ট গুলা কমা সেপারেটেড থাকে।
=[value1,value2,....valueN];
এখানে আমরা চাইলে ভ্যালু ওয়ানে স্ট্রিং, টু তে ইন্টিজার, এবং যেকোন পজিশনে যেকোন "ডেটা টাইপের" এলিমেন্ট ইনপুট দিতে পারব। লিস্ট একটি মিউটেবল ডেটা স্ট্রাকচার অর্থাৎ আমরা চাইলে লিস্টের ডেটা পরিবর্তন করতে পারব এবং এর জন্য পাইথন নতুন একটা লিস্ট তৈরি করে ফেলবে না।
লিস্টের ইন্ডেক্সিং শুরু হয় "০" শূন্য থেকে অর্থাৎ লিস্টে যদি n সংখ্যক এলিমেন্ট থাকে তাহলে এর সর্বশেষ উপাদানের ইন্ডেক্স হবে n-1.
অর্থাৎ একটি লিস্ট যদি এমন হয়ঃ list = ["python",67, 0.1, 'O' ]
এখানে ইন্ডেক্স ভ্যালু শুরু হবে ০ থেকে। প্রথম এলিমেন্ট থেকে ইন্ডেক্সিং করলে তাকে ফরোয়ার্ড ইন্ডেক্সিং বলে। আমরা চাইলে লিস্টকে ব্যাকওয়ার্ড ইন্ডেক্সিং ও করতে পারি সেক্ষেত্রে শেষ এলিমেন্ট থেকে ইন্ডেক্সিং শুরু হয় এবং মান হয় -১।
লিস্ট অপারেশনস
পাইথন লিস্টে আমরা এলিমেন্ট যোগ করা, বাদ দেয়া, আলাদা লিস্ট বানানো, দুটো লিস্ট যোগ করা সহ নানা রকমের অপারেশন চালাতে পারি।
কনকেটেনেটিং
দুটো লিস্ট একসাথে জুড়ে দেয়াকে লিস্ট কনকেটেনেশন বলে। পাইথনে লিস্ট কনকেটেনেশনের ক্ষেত্রে "+" অপারেটর ব্যবহার করা হয়। এখানে অবশ্যই অপারেন্ড দুটি লিস্ট টাইপের হতে হবে।
listA = ["a","b","c"]
listB = [1, 2, 3]
listADD = listA + listB
স্লাইসিং
একটি লিস্ট থেকে চাইলে একাধিক সাব লিস্ট তৈরি করা যায়।
>>> listA = [1,5,4,7,8,9]
>>>listA[2:]
[4,7,8,9]
>>>listA[:3]
[1,5,4]
>>>listA[1:4]
[5,4,7]
আপডেটিং
লিস্ট যেহেতু মিউটেবল বা পরিবর্তনীয় তাই আমরা চাইলে লিস্টের যেকোন জায়গায় যে কোন সময় এলিমেন্ট ইনপুট করতে পারি।
>>> listA=[6,8,9,3,5,1]
>>> listA[2] = 10
>>> listA
[6,8,10,3,5,1]
লিস্টের ২ নং ইন্ডেক্সে ভ্যালু ১০ ইনপুট কর। কিন্তু এক্ষেত্রে নতুন ডেটা লিস্টের আগের ডেটা কে রিপ্লেস কিরে ফেলবে।
এপেন্ডিং
এপেন্ড অর্থ যোগ করা। আমরা চাইলে লিস্টে একটি করে ডেটা ইনপুট করতে পারি তার জন্য এপেন্ড এক্সপ্রেশন ব্যবহার করা হয়।
>>>listA = [1,2,5,8,6]
>>>listA.append(7)
[1,2,5,8,6,7]
ডিলিটিং/ রিমোভিং
এপেন্ডের মত রিমোভ ফাংশন ব্যবহার করে লিস্ট থেকে একটি করে ডেটা রিমোভ/ডিলিট করা যায়।
>>>listA.remove(5)
[1,2,8,6,7]
listA তে যদি একাধিক 5 থাকত তাহলে সবগুলো 5 রিমোভ হওয়ার পরিবর্তে প্রথম যে 5 টি পাওয়া যেত পাইথন সেটি রিমোভ করে দিত।
>>>listA =[1,2,5,6,7,5,4]
>>>listA.remove(5)
[1,2,6,7,5,4]
লেনথ্
লিস্টের দৈর্ঘ্য বের করার জন্য len() ফাংশন ব্যবহার করা হয়।
>>>listA = (1,2,3)
>>>len(listA)
3
রিপিটিশন
একটি লিস্ট একাধিক বার আউটপুট হিসেবে চাইলে শুধু মাত্র সাধারণ গুণ করে দিলেই হয়। তবে লিস্ট গুলো আলাদা আলাদা লিস্ট আকারে প্রিন্ট না হয়ে একটি মাত্র লিস্ট আকারে প্রিন্ট হবে।
>>> li = ['T','C','O']
>>> li*2
['T', 'C', 'O', 'T', 'C', 'O']
ম্যাক্সিমাম-মিনিমাম এলিমেন্ট
একটি লিস্টের সবচেয়ে বড়/ছোট উপাদান বের করতে লিস্টে ও max() এবং min() ফাংশন ব্যবহার করা হয়ে থাকে।
>>> listA=( 2,6,7,9)
>>>max(listA)
9
>>>min(listA)
2
মেম্বারশিপ
কোন একটা উপাদান একটি লিস্টের মেম্বার কিনা তাও চেক করা যায়। তার জন্য in কী-ওয়ার্ড ব্যবহার করা হয়।
>>>listA = [1,2,3,4]
>>>3 in listA
True
>>> if 3 in listA:
print("Present")
else:
print("Absent")
Present
খ. ট্যুপল
টাপল হচ্ছে পাইথনের একটি বিল্ট ইন ডেটা স্ট্রাকচার। ট্যুপল আর লিস্টের মধ্যে বেসিক পার্থক্য হচ্ছে ট্যুপল ইমিউটেবল। মানে ট্যুপলে কোন পরিবর্তন করা যায় না। ট্যুপল লিখতে আমরা ফার্স্ট ব্রাকেট না প্যারেনথিসিস ব্যবহার করি। tup = () #empty tuple
লিস্টের মত ট্যুপলে ও আমরা এলিমেন্ট গুলো কমা সেপারেটেড করে লিখি। tup = (1,3,4,7)
বলে রাখা ভাল ট্যুপলে চাইলে আমরা প্যারেনথিসিস ব্যবহার না ও করতে পারি। সেক্ষত্রে ও পাইথন একে ট্যুপল অবজেক্ট হিসেবেই নিবে।
tup = "y"," a", "r"
ট্যুপল অপারেশনস্
পাইথন ট্যুপলে আমরা এলিমেন্ট যোগ করা, বাদ দে্যা, দুটো টুপলের তূলনা করা সহ নানা রকমের অপারেশন চালাতে পারি।
আপডেট
টুপল যেহেতু অপরিবর্তনীয় (ইমিউটেবল) তাই টুপলে সিঙ্গলে ভ্যালু আপডেট/ইনসার্ট করতে পারব না। তবে একাধিক টুপল যোগ/ কনক্যাট করা যায়।
tup1 = ("y","a","r")
tup2 = (1,2,3)
tup3 = tup1 + tup2
print(tup3)
আউটপুটঃ ("y","a","r",1,2,3)
ডিলিট
পাইথনে টুপল ডিলিট করার জন্য del স্টেটমেন্ট ব্যবহার করা হয় । তবে এতে পুরো টুপলই ডিলিট হয়ে যায়।
>>>del tup3
>>>print(tup3)
এই কোড রান করাতে গেলে এমন এরর আসবে... NameError: 'tup3' is not defined
কারণ পাইথন পুরো ট্যুপল টা- ই ডিলিট করে দিয়েছে।
লেনথ্
ট্যুপলের লেনথ্ বের করার জন্য লিস্টের মত len() এক্সপ্রেশন ব্যবহার করা হয়।
>>>tup = (1,2,3)
>>>len(tup)
3
রিপিটিশন
একটি ট্যুপল একাধিক বার আউটপুট হিসেবে চাইলে শুধু মাত্র সাধারণ গুণ করে দিলেই হয়। তবে ট্যুপল গুলো আলাদা আলাদা ট্যুপল আকারে প্রিন্ট না হয়ে একটি মাত্র ট্যুপল আকারে প্রিন্ট হবে।
>>>tup*3
(1,2,3,1,2,3,1,2,3)
ম্যাক্সিমাম-মিনিমাম এলিমেন্ট
একটি ট্যুপলের সবচেয়ে বড়/ছোট উপাদান বের করতে লিস্টের মত ট্যুপলে ও max() এবং min() ফাংশন ব্যবহার করা হয়ে থাকে।
>>> tup=( 2,6,7,9)
>>>max(tup)
9
>>>min(tup)
2
মেম্বারশিপ
কোন একটা উপাদান একটি টুপলের মেম্বার কিনা তাও চেক করা যায়।
>>>tuple = (1,2,3,4)
>>>3 in tuple
True
>>> if 3 in tuple:
print("Present")
else:
print("Absent")
এক্সেসেসিং, ইনডেক্সিং, স্লাইসিং ইন ট্যুপল
ট্যুপলের উপাদান গুলো এক্সসেস/ট্রাভার্স করার জন্য আমরা লিস্টের মত ইন্ডেক্সিং এর সাহায্য নিতে পারি৷ ট্যুপলের ক্ষেত্রে ও ফরওয়ার্ড ইন্ডেক্সিং শুরু হয় ০ থেকে এবং ব্যাকওয়ার্ড ইন্ডেক্সিং শুরু হয় -১ থেকে।
>>> tuple = (4,3,7,6)
>>> tuple[1]
3
>>>tuple[-1]
6
একটা ট্যুপলের এক বা একাধিক উপাদান কেটে/স্লাইস করে নিয়ে চাইলে অন্য আরেকটি টুপল তৈরি করা যায়। একে স্লাইসিং বলে।
>>> tuple = (2,5,7,9,5)
>>> tuple[1:]
(5,7,9,5)
এর মানে ইন্ডেক্স ১ থেকে শুরু করে পরের সব গুলো উপাদান।
>>>tuple[:3]
(2,5,7,9)
এর মানে হচ্ছে ০ শূন্য ইন্ডেক্স থেকে ৩ নং ইন্ডেক্স পর্যন্ত উপাদান গুলো।
>>>tuple[1:3]
(5,7)
এর মানে হচ্ছে ইন্ডেক্স নং ১ থেকে শুরু করে ৩ নং ইন্ডেক্সের আগ পর্যন্ত সকল উপাদান তবে ৩নং ইন্ডেক্স নয়।
২। সেট টাইপ
ক. সেট
সেট পাইথনের একটি ইমিটেবল ডেটা টাইপ। ডিকশিনারির মত পাইথনে সেট লিখার জন্য কার্লি ব্রেসিস {} ব্যবহার করা হয়, তবে এখানে ডিকশিনারির মত "কি-ভ্যালু" পেয়ার থাকে না। ডেটা গুলো অবিন্যস্ত অবস্থায় থাকে। আবার set() মেথড দিয়ে ও সেট ক্লাসের অবজেক্ট তৈরি করা যায়৷ সেটের প্রতিটি ভ্যালু ই হয় ইউনিক। মানে তুমি চাইলে একই ডেটা একাধিক বা রাখতে পার কিন্তু পাইথন সেসব বাদ দিয়ে প্রত্যেকটি ডেটা একবার করে রাখবে।
>>> a_set={'a','b','c','d','c'}
>>> type(a_set)
<class 'set'>
>>> a_set
{'c', 'd', 'b', 'a'}
এখানে আমি ‘a’ এবং ‘c’ দু’বার করে রাখলে ও পাইথন সেগুলোকে একবার করে সেটে জমা করেছে।
সেট অপারেশন্স
আমরা গণিতে সেটের সমাধান করার সময় সেটে নতুন উপাদান যোগ করা বা বাদ দেয়া ছাড়া ও ইউনিয়ন, ইন্টারসেকশন ইত্যাদি অপারেশন চালাতে পারতাম। পাইথন সেট ও এর ভিন্ন নয়।
আপডেট
কোন সেটে নতুন কোন মেম্বার যোগ করার জন্য add() মেথড ব্যবহার করা হয়।
>>>a_set = {'a','b','c','d'}
>>>a_set.add('e'}
>>>print(a_set)
{'a','b','c','d','e'}
তবে add() মেথড ব্যবহার করে আমরা প্রতিবারে একটির বেশি এলিমেন্ট যোগ করতে পারব না। একসাথে একাধিক এলিমেন্ট যোগ করার জন্য update() মেথড ব্যবহার করতে হয়।
>>>a_set = {'a','b','c','d'}
>>>a_set.update('e','f','g'}
>>>print(a_set)
{'a','b','c','d','e','f','g'}
ডিলিটং
সেটের এলিমেন্ট ডিলিট করার জন্য discard(),remove(),pop() এই তিনটি মেথড ব্যবহার করা হয়। pop() মেথড একেক বার একেক এলিমেন্ট কে ডিলিট করে। কারণ সেট অন্যান্য ডেটা টাইপের মত ইন্ডেক্সিং সাপোর্ট করে না।
>>>a_set = {'a','b','c','d'}
>>>a_set.pop()
>>>print(a_set)
{'a','b','c'}
discard() এবং remove() মেথড একই কাজ করে, তবে একটি পার্থক্য হলঃ
discard() মেথড ব্যবহার করে যদি কোন এলিমেন্ট ডিলিট করতে হয় তবে সে এলিমেন্ট যদি সেটে না থাকে তাহলে ও পাইথন কোন এরর মেসেজ দেখাবে না।
কিন্তু remove () মেথডের ক্ষেত্রে যে এলিমেন্ট আমরা ডিলিট করব সেটি সেটে অবশ্যই থাকতে হবে তা না হলে পাইথন এরর দেখাবে৷
>>> a_set = {'a','v','d'}
>>> type(a_set)
<class 'set'>
>>> a_set.remove('a')
>>> a_set
{'d', 'v'}
>>> a_set.discard('a')
>>> a_set.remove('a')
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
a_set.remove('a')
KeyError: 'a'
ইন্ডেক্সিং
সেট অন্যান্য ডেটা টাইপের মত ইন্ডেক্সিং সাপোর্ট করে না। তুমি যদি কোন সেটের এলিমেন্ট কে তার ইন্ডেক্স দিয়ে এক্সেস করতে চান তাহলে এরর দেখাবে।
>>>a_set = {'a','b',1,'c'}
>>>print(a_set[0])
TypeError: 'set' object does not support indexing
এ কারনেই আমরা যখন add() বা update() ফাংশন ব্যবহার করি তখন একেক বার একের জায়গায় এলিমেন্ট যোগ হয়।
ইউনিয়ন
দু’টো বা তার বেশি সেটের সব উপাদান গুলো যোগ করার পদ্ধতিকে সেট ইউনিয়ন বলে।
>>> a = {'a','b','c'}
>>> b = {'1','2','3'}
>>> a|b
{'3', '2', 'a', 'c', 'b', '1'}
>>> c = {1,2,3}
>>> a|b|c
{1, '3', '2', 2, 3, 'a', 'c', 'b', '1'}
এখানে লক্ষ করবে সেট গুলোতে ভিন্ন ধরনের ডেটা থাকা সত্ত্বেও সেট গুলোর মধ্যে ইউনিয়ন অপারেশন চালানো সম্ভব।
ইন্টারসেকশন
দুই বা ততোধিক সেটের উপাদান গুলো থেকে সব সেটেই বিদ্যমান এমন উপাদান বের করার পদ্ধতিকে সেট ইন্টারসেকশন বলে।
>>> a&b&c
set()
>>> a = {'a','b','c'}
>>> b = {'b','c','d'}
>>> a&b
{'c', 'b'}
সেট ডিফারেন্স
একটি সেট থেকে আরেকটি সেট বাদ দেয়াকে সেট ডিফারেন্স বলে।
>>> a-b
{'a'}
এছাড়া ও কোন উপাদান সেটে আছে কিনা। কোন সেটে অন্য কোন সেটের সাবসেট কিনা ইত্যাদি অপারেশন পাইথন সেট এ করা যায়।
>>> 'a' in a
True
>>> 's' in a
False
>>> a = {'a','b'}
>>> b = {'a'}
>>> a > b #subset
True
>>> a < b
False
খ. ফ্রোজেন সেট
ফ্রোজেন অর্থ জমাটবদ্ধ। আমরা সাধারনত সেট’এ এলিমেন্ট যোগ করা,বিয়োগ করা, সহ নানা অপারেশন চালাতে পারি। কিন্তু ফ্রোজেন সেট হচ্ছে একটি জমাটবদ্ধ সেট যাকে পরিবর্তন করার অনুমতি পাইথন আমাদের দেয় না।
>>> a = frozenset()
>>> a.add(3)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
a.add(3)
AttributeError: 'frozenset' object has no attribute 'add'
৩। ম্যাপিং
ম্যাপিং টাইপ ডেটা টাইপের বৈশিষ্ট্য হল অন্যান ডেটা টাইপের মত এদের কোন ইনডেক্স নেই বরং প্রতিটি ডেটার সাথে একটি ‘কি’ দেয়া থাকে যার মাধ্যমে সে ‘কি’ তে থাকা ভ্যালু কে আমরা এক্সেস করতে পারি। এই ‘কি’ এবং ‘ভ্যালু’র জোড় কে ‘কি-ভ্যালু পেয়ার’ বলে।
ক. ডিকশনারি
ডিকশনারি পাইথনের একটি বিল্ট ইন ডেটা টাইপ। ডিকশনারি তে প্রতিটি এলিমেন্ট এর দুটো অংশ থাকে। "কি" এবং "ভ্যালু"। "কি" হচ্ছে এলিমেন্টের ইন্ডেক্স বা এলিমেন্ট নির্দেশক। আর ভ্যালু হচ্ছে এলিমেন্টের ভ্যালু। প্রতিটা "কি" অবশ্যই ইউনিক হতে হয় তবে একাধিক ভ্যালু একইরকম হতে পারে। ডিকশনারি প্রকাশ করতে পাইথনে কার্লিব্র্যাসি { } ব্যবহার করা হয়। ডিকশনারি তে এলিমেন্ট গুলোর "কি" এবং "ভ্যালু" সেমিকোলন ( : ) দ্বারা সেপারেটেডে থাকে এবং প্রত্যেকটা এলিমেন্ট কমা ( , ) সেপারেটেড করে লিখা হয়।
dictA = {
"key1" : "value1",
"key2" : "value2",
"key3" : "value2",
}
আমরা চাইলে ডিকশনারিতে বিভিন্ন টাইপের ভ্যালু রাখতে পারি কিন্তু 'কি' গুলো অবশ্যই ইমিউটেবল ডেটা টাইপের হতে হবে। যেমনঃ স্ট্রিং,নাম্বার,টুপ্যল।
এক্সেসিং ভ্যালু
লিস্ট এবং ট্যুপলে ডেটা এক্সেস করার জন্য ইন্ডেক্সিং এর ব্যবহার করছি। কিন্ত ডিকশনারির ডেটা এক্সেস করার জন্য আমরা এর 'কি' গুলো ব্যবহার করি।
>>>dic = {"First" : "Red",
"Second" : "Yellow",
"Third" : "Green"
}
>>>print(dic[‘Second’])
"Yellow"
>>> dic.values()
dict_values(['Red', 'Yellow', 'Green'])
আবার যদি এমন কোন 'কি' কল করা হয় যে নামে কোন 'কি' ডিকশনারিতে নেই তখন KeyError এক্সেপশন রেইজ করবে। আমরা ডিকশনারির ভ্যালু থেকে ও এর key বের করতে পারব।
dic ={"a":1, "b":2, "c":3}
keys = list(dic.keys())
values = list(dic.values())
print(keys [values.index(1)])
print(keys [values.index(3)])
আউটপুটঃ a c প্রথমে ডিকশনারির কী ও ভ্যালু গুলোকে লিস্ট অবজেক্টে রূপান্তর করে নিয়েছি। তারপর লিস্টের index() অ্যাট্রিবিউট ব্যবহার করে values লিস্টের এলিমেন্টের ইন্ডেক্স বের করেছি ও এ ভ্যালুকে keys লিস্টে ইনডেক্স হিসেবে পাস করেছি।
এই কাজটা অন্যভাবে ও করা যায়ঃ
def get_key(val):
for key, value in dic.items():
if val == value:
return key
return "key doesn't exist"
dic ={"a":1, "b":2, "c":3}
print(get_key(1))
print(get_key(2))
আউটপুটঃ a b
আমাদের যে ভ্যালুর key দরকার সে ভ্যালুটা আমরা get_key() ফাংশন আর্গুমেন্ট হিসেবে পাস করেছি।get_key() ফাংশন লিস্টের আইটেম গুলোর মধ্যে সেই ভ্যালু সার্চ করে, খেয়াল করে দেখ এখানে key এবং value দুটোই ইটারেটর তাই প্রতিবার লুপেই key-value জোড় সেটাই হবে যেটা ডিকশনারিতে আছে। value আর্গুমেন্টের সাথে মিলে গেলে get_key() সেই key-value জোড়ের key টি রিটার্ন করে দিbe আর না মিললে “key doesn’t exist” রিটার্ন করে দিবে।
আপডেট
ডিকশনারি একটি মিউটেবল ডেটা টাইপ,আমরা চাইলে যেকোন সময় ডিকশনারি আপডেট করতে পারি৷ নিচের নিয়মে ডিকশনারি তে নতুন এন্ট্রি বা পুরোনো এন্ট্রি আপডেট করতে হয়...
>>>dictionary = { 'Name' : 'Nadim', 'Roll' : '67', 'Dept' : 'CSE' }
>>>dictionary[ 'Name' ] = 'Chowdhury' #Updating existing entry
>>>dictionary[ 'Sec' ] = 'A' #Adding new entry
অথবা ডিকশনারির update() অ্যাট্রিবিউট ও ব্যবহার করা যায়।
car = {“brand”:”ford”,
“model”:”mustang”,
“year”:1995
}
car.update({“color”:”red”})
ডিলিট
ডিকশনারি তে সিঙ্গেল এলিমেন্ট, সব এলিমেন্ট বা পুরো ডিকশনারি ই ডিলিট করে দেয়া যায়। পুরো ডিকশনারি ডিলিট করতে del স্টেটমেন্ট ব্যবহার করা হয়৷
>>>dictionary = {'Name' : 'Nadim', 'Roll' : '67', 'Dept' : 'CSE' }
>>>del dictionary['Dept'] #removing single element
>>>dictionary.clear() #removing all the elements
>>>del dictionary[ ] #removing the total dictionary
নেস্টেড ডিকশনারি
যদি একটি ডিকশনারি ভিতরে আরো ডিকশনারি থাকে তাহলে আমরা কিভাবে সে ডিকশনারি থেকে ভ্যালু বের করে আনব? ধরি আমাদের নিম্নের মত একটি ডিকশনারি আছে...
dictionary = {"Class_One" : {'roll_1':'Rabib','roll_2':'Rujhan','roll_3':'Ahabab'},
"Class_Two" : {'roll_1':'Yash','roll_2':'Shabab','roll_3':'Sadman'},
"Class_Three": {'roll_1':'Awan','roll_2':'Arabi','roll_3':'Jaha'},
}
আমরা যদি ক্লাস ওয়ানের রোল এক এর নাম জানতে চাই তাহলে কিভাবে জানতে পারবে? হয়তো ক্লাস ওয়ান কে আলাদা করে তারপর আবার তার “কি” দিয়ে এক্সেস করতে পারবে। কিন্তু আমরা একই লাইনের মাধ্যমেই ডেটা এক্সেস করতে পারবে।
>>> dictionary["Class_One"]['roll_1']
Rabib
এখানে প্রথম “কি” টা["Class_One"] মেইন ডিকশনারির “কি”। এই “কি” এর ভ্যালু হিসেবে যে ডিকশনারি টি রিটার্ন হবে সে ডিকশনারি “কি” হচ্ছে এর পরের “কি” ['roll_1'] এবং এই স্টেট মেন্ট টি এর ডেটা ই রিটার্ন করবে।
>>>world = {'Europe': {"France": {'Capital': "Paris"},
"Germany": {'Capital': "Berlin"},
"Spain": {'Capital': "Madrid"}},
'Asia': {"Japan": {'Capital': "Tokyo"},
"Bangladesh":{'Capital': "Dhaka"},
"India":{'Capital': "New Delhi"}}
}
>>>world['Asia']["Bangladesh"]['Capital']
Dhaka
এভাবে যত ইচ্ছা নেস্টেড ডিকশনারি এক্সেস করা যায়। জেসন JSON টাইপের ডেটা ও একই ভাবে এক্সেস করা হয়।
খ। কাউন্টার
অন্যান্য কালেকশন ডেটা টাইপের (list, tuple, dict) মত পাইথনের collection মডিউলের একটি ডেটা টাইপ বা ডেটা স্ট্রাকচার হচ্ছে counter. counter মূলত count ফাংশনের কাজ করে। তবে এটি একটি পুরো ডেটা সেটের বিভিন্ন ডেটার আলাদা আলাদা সংখ্যা গণনা করে।এটি dict ক্লাসের একটি সাবক্লাস। counter ডেটা টাইপে লিস্ট,টুপল,স্ট্রিং রাখা যায়। এটি একটি ডিকশিনারি রিটার্ণ করে। যার 'কি' হচ্ছে লিস্টের প্রতিটি ইউনিক ভ্যালু এবং 'ভ্যালু' হল সে এলিমেন্ট লিস্টে কত বার আছে তার মান।
>>>from collections import Counter
>>>s = Counter('sfsjsbfajs')
>>>s
Counter({'s': 4, 'f': 2, 'j': 2, 'b': 1, 'a': 1})
>>>
>>>c = Counter(['a','b','a','a',1,4,1,1,'b'])
>>>c
Counter({'a': 3, 1: 3, 'b': 2, 4: 1})
>>> t = Counter((1,3,1))
>>>t
Counter({1: 2, 3: 1})
>>>type(t)
<class 'collections.Counter'>
>>>issubclass(Counter,dict)
True
আমরা কাউন্টার ডেটা টাইপে একটি মাত্র আর্গুমেন্ট পাস করতে পারব। অর্থাৎ একটি লিস্ট বা একটি স্ট্রিং বা একটি ট্যুপল। এক সাথে একাধিক আর্গুমেন্ট পাঠানো যাবে না তাহলে এক্সেপশন দেখাবে।
>>> from collections import Counter
>>> c = Counter(['a','a','b'],[1,2,3,'a'])
TypeError: expected at most 1 arguments, got 2
এছাড়া ও পাইথন Counter() এ কি- ওয়ার্ড আর্গুমেন্ট পাস করা যায়৷
আপডেটিং
অন্যান্য কালেকশন ডেটা টাইপের মত Counter ও আপডেট করা যায়।একটি এম্পটি কাউন্টার বা এক্সিস্টিং কোন কাউন্টারেও নতুন এলিমেন্ট যোগ করা যায়।
>>>c = Counter()
# defining an empty Counter
>>>c.update("a")
# adding values to "c"
>>>c
Counter({a:1})
>>>c.update("aab")
>>>c
Counter({a:3,b:1})
ডিলিটিং
কাউন্টার ডেটা টাইপ থেকে কোন ডেটা ডিলিট করার জন্য subtract() ফাংশন ব্যবহার করা হয়৷
>>>c.subtract('a')
>>>c
Counter({'a':2, 'b':1})
>>>c.subtract('ab')
>>>c
Counter({'a':1, 'b':0})
এক্সেসিং
Counter এর গঠন পুরোপুরি ডিকশেনারির মতই৷ এর এলিমেন্ট গুলো এক্সেস ও করা যায় ডিকশনারির মত 'কি' ব্যবহার করে। তবে ডিকশিনারির ক্ষেত্রে কোন কি যদি অনুপস্থিত থাকত আমরা KeyError পেতাম, এক্ষেত্রে কাউন্টার আমাদের "শূন্য" পাঠাবে।
>>>c['a']
3
>>>c['d']
0
আমরা যদি কোন 'কি' এর ভ্যালু বাড়াতে চাই মানে "a" এর মান "3" থেকে বাড়াতে বা কমাতে চাই তাহলে সে কি এর ভ্যালু রি-অ্যাসাইন করে দিতে হবে।
>>>c['a'] = 2
>>>c
Counter ({'a':2, 'b':1})
কাউন্টারের আরেকটি ফাংশন হল elements(). এ ফাংশন টি কাউন্টারের ভেতর থাকা প্রতিটি এলিমেন্ট একটি ইটারেটর অবজেক্ট আকারে আউটপুট দেয়৷ তবে এর হিউম্যান রিডেবল ফরম্যাট পেতে আমাদের এটিকে লিস্টে কনভার্ট কর নিতে হয়।
>>>c.elements()
<itertools.chain object at 0x7c07339860>
>>>list(c.elements())
Counter ('a', 'a', 'b')
এখানে লক্ষনীয় যে, কাউন্টারের ভেতর যে এলিমেন্ট(কি) এর মান(ভ্যালু) যত ছিল সেই এলিমেন্ট ঠিক ততবার আলাদা আলাদা ভাবে যুক্ত হয়েছে।
কাউন্টার একটি কন্টেইনার যা কোন ডেটাসেটে কোন ডেটা কত সংখ্যক বার রয়েছে তার ভ্যালু ধারন করে।