ডেটা সায়েন্সে পাইথনের সাধারণ সিনট্যাক্স (মৌলিক)

গত দু’দিন ধরে আমি Data Science from Scratch বইটি পড়ছি (PDF লিঙ্ক)। এটি ডেটা সায়েন্সের একটি দারুণ, সহজবোধ্য সূচনা গ্রন্থ। বইটির একটি অধ্যায়ে পাইথনের মৌলিক সিনট্যাক্স এবং ডেটা সায়েন্সে ব্যবহৃত কিছু উন্নত সিনট্যাক্স খুব সুন্দর ও পরিষ্কারভাবে আলোচনা করা হয়েছে। আমার মনে হয়েছে আলোচনাটি বেশ ভালো, তাই এটিকে অনুবাদ করে এখানে রেখে দিলাম যাতে ভবিষ্যতে কাজে লাগে।
ডেটা সায়েন্সে ব্যবহৃত পাইথনের সাধারণ সিনট্যাক্স (মৌলিক)
ডেটা সায়েন্সে ব্যবহৃত পাইথনের সাধারণ সিনট্যাক্স (উন্নত)

এই অধ্যায়ে ডেটা প্রক্রিয়াকরণে অত্যন্ত দরকারী পাইথনের মৌলিক সিনট্যাক্স এবং ফাংশনগুলো (পাইথন ২.৭ এর উপর ভিত্তি করে) আলোচনা করা হয়েছে।

ইনডেন্টেশন

অনেক প্রোগ্রামিং ভাষা কোড ব্লক নিয়ন্ত্রণ করতে ব্র্যাকেট ব্যবহার করে, কিন্তু পাইথন ইনডেন্টেশন ব্যবহার করে:

for i in [1, 2, 3, 4, 5]:  
    print i          # "for i" লুপের প্রথম লাইন  
    for j in [1, 2, 3, 4, 5]:  
        print j      # "for j" লুপের প্রথম লাইন  
        print i + j  # "for j" লুপের শেষ লাইন  
    print i          # "for i" লুপের শেষ লাইন  
print "done looping"  

এ কারণে পাইথনের কোড পড়া খুবই সহজ, তবে এর মানে হলো আপনাকে ফরম্যাটিংয়ের দিকে সবসময় খেয়াল রাখতে হবে। ব্র্যাকেটের ভেতরের অতিরিক্ত স্পেস উপেক্ষা করা হয়, যা লম্বা এক্সপ্রেশন লেখার সময় খুব কাজে আসে:

long_winded_computation = (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20)  

এটি কোডকে আরও পঠনযোগ্য করে তোলে:

list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  
easier_to_read_list_of_lists = [ [1, 2, 3],  
                                 [4 ,5 ,6 ],  
                                 [7 ,8 ,9 ] ]  

একাধিক লাইনের স্টেটমেন্ট

ব্যাকস্ল্যাশ ব্যবহার করে দুটি বিচ্ছিন্ন লাইনকে যুক্ত করা যায় (তবে এই পদ্ধতি খুব কম ব্যবহার করা হয়):

two_plus_three = 2 + \
                 3  

মডিউল (Modules)

পাইথনে বিল্ট-ইন মডিউল হোক বা থার্ড-পার্টি মডিউল, ব্যবহারের জন্য সেগুলোকে ম্যানুয়ালি ইম্পোর্ট করতে হয়।

  1. পুরো মডিউলটি সরাসরি ইম্পোর্ট করা:

    import re  
    my_regex = re.compile("[0-9]+", re.I)  

    এখানে re মডিউলটি রেগুলার এক্সপ্রেশনের জন্য ব্যবহার করা হয়েছে। মডিউল ইম্পোর্ট করার পর, এর ফাংশনগুলো re. প্রিফিক্স ব্যবহার করে সরাসরি কল করা যায়।

  2. যদি ইম্পোর্ট করা মডিউলের নামটি আপনার কোডে ইতিমধ্যে ব্যবহার করা হয়ে থাকে, তাহলে মডিউলটি ইম্পোর্ট করার সময় এটিকে অন্য একটি নামে ম্যাপ করা যেতে পারে:

    import re as regex  
    my_regex = regex.compile("[0-9]+", regex.I)  
  3. যদি আপনি ‘দুষ্টু’ হন, তাহলে আপনি পুরো মডিউলটিকে বর্তমান নেমস্পেসে ইম্পোর্ট করতে পারেন। এতে আপনার আগে থেকে সংজ্ঞায়িত কোনো ভ্যারিয়েবল অসাবধানতাবশত ওভাররাইড হয়ে যেতে পারে:

    match = 10  
    from re import *  # re মডিউলে একটি match ফাংশন আছে  
    print match       # match ফাংশনটি আউটপুট দেবে  

    তবে যেহেতু আপনি একজন ভালো মানুষ, আমি বিশ্বাস করি আপনি এমনটা করবেন না।

গাণিতিক অপারেশন (Arithmetic)

পাইথন ২.৭ ডিফল্টভাবে পূর্ণসংখ্যা ভাগ ব্যবহার করে, তাই $ 5 / 2 = 2 $। কিন্তু অনেক সময় আমরা পূর্ণসংখ্যা ভাগ চাই না, তখন এই মডিউলটি ইম্পোর্ট করা যেতে পারে:

from __future__ import division  

এটি ইম্পোর্ট করার পর $5 / 2 = 2.5$ হবে।
পূর্ণসংখ্যা ভাগ (ফ্লোর ডিভিশন): $5 // 2 = 2$।

ফাংশন (Functions)

ফাংশন সংজ্ঞা

একটি ফাংশন হলো এমন একটি নিয়ম যা শূন্য বা তার বেশি ইনপুট গ্রহণ করে এবং নির্দিষ্ট আউটপুট প্রদান করে। পাইথনে আমরা def ফাংশন_নাম(আর্গুমেন্ট) ব্যবহার করে একটি ফাংশন তৈরি করি:

def double(x):  
    """এখানে আপনি ফাংশনের কার্যকারিতা সম্পর্কে কিছু ব্যাখ্যা লিখতে পারেন।  
    যেমন, এই ফাংশনটি ইনপুটকে ২ দিয়ে গুণ করবে।"""  
    # ফাংশনের মূল অংশ এখানে লেখা যেতে পারে, ইনডেন্টেশন মনে রাখবেন।  
    return x * 2  

ফাংশন ব্যবহার

পাইথনে ফাংশনগুলো “ফার্স্ট-ক্লাস সিটিজেন” হিসেবে বিবেচিত হয়। এর মানে হলো আমরা একটি ফাংশনকে একটি ভ্যারিয়েবলে অ্যাসাইন করতে পারি, অথবা এটিকে অন্য ফাংশনের আর্গুমেন্ট হিসেবেও পাস করতে পারি:

def apply_to_one(f):  
    """ফাংশন f কে কল করে এবং 1 কে আর্গুমেন্ট হিসেবে পাস করে"""  
    return f(1)  
my_double = double          # double আগের সেকশনে সংজ্ঞায়িত ফাংশনটিকে নির্দেশ করে  
x = apply_to_one(my_double) # x এর মান 2 হবে  

বেনামী ফাংশন

lambda ব্যবহার করে বেনামী ফাংশনও তৈরি করা যায়:

y = apply_to_one(lambda x: x + 4)     # এর মান 5 হবে  

আপনি lambda কে অন্য কোনো ভ্যারিয়েবলে অ্যাসাইন করতে পারেন, তবে বেশিরভাগ ডেভেলপাররা def ব্যবহার করার পরামর্শ দেন:

another_double = lambda x: 2 * x      # এটি সুপারিশ করা হয় না  
def another_double(x): return 2 * x   # এটি সুপারিশ করা হয়  

অতিরিক্ত তথ্য:

ফাংশন আর্গুমেন্ট পাস করা

ফাংশন আর্গুমেন্টগুলোর ডিফল্ট মান থাকতে পারে। যদি ফাংশন কল করার সময় কোনো আর্গুমেন্ট না দেওয়া হয়, তাহলে ডিফল্ট মান ব্যবহার করা হয়; আর যদি আর্গুমেন্ট দেওয়া হয়, তাহলে সেই নির্দিষ্ট মানটি ব্যবহৃত হয়:

def my_print(message="my default message"):  
    print message  
my_print("hello")     # আউটপুট "hello"  
my_print()            # আউটপুট "my default message"  

কখনও কখনও আর্গুমেন্টের নাম ব্যবহার করে সরাসরি মান নির্দিষ্ট করাও খুব কার্যকর:

def subtract(a=0, b=0):  
    return a - b  
subtract(10, 5)   # রিটার্ন করবে 5  
subtract(0, 5)    # রিটার্ন করবে -5  
subtract(b=5)     # আগেরটির মতোই, রিটার্ন করবে -5  

স্ট্রিং (Strings)

একক উদ্ধৃতি (') অথবা দ্বৈত উদ্ধৃতি (") ব্যবহার করে স্ট্রিং তৈরি করা যায় (উদ্ধৃতি অবশ্যই জোড়া হতে হবে):

single_quoted_string = 'data science'  
double_quoted_string = "data science"  

এস্কেপ ক্যারেক্টার বোঝাতে ব্যাকস্ল্যাশ ব্যবহার করা হয়, যেমন:

tab_string = "\t"      # একটি ট্যাব ক্যারেক্টার  
len(tab_string)        # এর মান 1 হবে  

যখন আপনি ব্যাকস্ল্যাশ নিজেই ব্যবহার করতে চান (উইন্ডোজ ডিরেক্টরি বা রেগুলার এক্সপ্রেশনের জন্য), তখন r"" ব্যবহার করে একটি র-স্ট্রিং (raw string) তৈরি করতে পারেন:

not_tab_string = r"\t" # এর অর্থ ক্যারেক্টার '\' এবং 't'  
len(not_tab_string)    # এর মান 2 হবে  

তিনটি দ্বৈত উদ্ধৃতি ব্যবহার করে মাল্টি-লাইন স্ট্রিং তৈরি করা যায়:

multi_line_string = """এটি প্রথম লাইন  
এটি দ্বিতীয় লাইন  
এটি তৃতীয় লাইন"""  

এক্সেপশন হ্যান্ডলিং (Exception)

যখন প্রোগ্রামে কোনো ত্রুটি ঘটে, তখন পাইথন একটি এক্সেপশন তৈরি করে। যদি আমরা এটিকে হ্যান্ডেল না করি, তাহলে প্রোগ্রামটি বন্ধ হয়ে যাবে। try এবং except স্টেটমেন্ট ব্যবহার করে এক্সেপশন ধরা যায়:

try:  
    print 0 / 0  
except ZeroDivisionError:  
    print "শূন্য দিয়ে ভাগ করা যাবে না"  

যদিও অন্যান্য ভাষায় এক্সেপশনকে খারাপ জিনিস হিসেবে দেখা হয়, তবে পাইথনে এক্সেপশন হ্যান্ডলিং ব্যবহার করলে আপনার কোড আরও পরিষ্কার এবং সংক্ষিপ্ত হয়।

লিস্ট (Lists)

লিস্ট তৈরি

লিস্ট হলো সহজ, সুবিন্যস্ত কালেকশন এবং এটি পাইথনের সবচেয়ে মৌলিক ডেটা স্ট্রাকচার (অন্যান্য ভাষার অ্যারের মতো, তবে লিস্টের কিছু অতিরিক্ত বৈশিষ্ট্য আছে)। একটি লিস্ট তৈরি করা:

integer_list = [1, 2, 3]  
heterogeneous_list = ["string", 0.1, True]  
list_of_lists = [ integer_list, heterogeneous_list, [] ]  
list_length = len(integer_list)   # এর মান 3 হবে  
list_sum = sum(integer_list)      # এর মান 6 হবে  

লিস্টের উপাদান অ্যাক্সেস করা

আপনি স্কোয়ার ব্র্যাকেট ([]) ব্যবহার করে লিস্টের উপাদানগুলো ইনডেক্স করতে পারেন:

x = range(10)       # লিস্ট x = [0, 1, ..., 9] পাওয়া যায়  
zero = x[0]         # এর মান 0 হবে, লিস্টের ইনডেক্স 0 থেকে শুরু হয়  
one = x[1]          # এর মান 1 হবে  
nine = x[-1]        # এর মান 9 হবে, লিস্টের শেষ উপাদান  
eight = x[-2]       # এর মান 8 হবে, লিস্টের শেষ থেকে দ্বিতীয় উপাদান  
x[0] = -1           # বর্তমান লিস্ট x = [-1, 1, 2, 3, ..., 9]  

লিস্ট স্লাইসিং

স্কোয়ার ব্র্যাকেট ব্যবহার করে লিস্ট স্লাইস করা যায়:

first_three = x[:3]                  # [-1, 1, 2]  
three_to_end = x[3:]                 # [3, 4, ..., 9]  
one_to_four = x[1:5]                 # [1, 2, 3, 4]  
last_three = x[-3:]                  # [7, 8, 9]  
without_first_and_last = x[1:-1]     # [1, 2, ..., 8]  
copy_of_x = x[:]                     # [-1, 1, 2, ..., 9]  

কোনো উপাদান লিস্টে আছে কিনা তা in ব্যবহার করে দেখা যায়:

1 in [1, 2, 3]        # True  
0 in [1, 2, 3]        # False  

এই উপায়ে উপাদান খোঁজা খুব অদক্ষ, তাই শুধুমাত্র ছোট লিস্টের ক্ষেত্রে অথবা যখন খোঁজার সময় আপনার কাছে খুব গুরুত্বপূর্ণ না হয়, তখনই এটি ব্যবহার করুন।

লিস্ট একত্রিত করা

পাইথনে দুটি লিস্টকে খুব সহজে একত্রিত করা যায়:

x = [1, 2, 3]  
x.extend([4, 5, 6])   # বর্তমান x = [1,2,3,4,5,6]  

যদি আপনি মূল লিস্ট x পরিবর্তন করতে না চান, তাহলে “যোগ” অপারেটর ব্যবহার করে একটি নতুন লিস্ট তৈরি করতে পারেন:

x = [1, 2, 3]  
y = x + [4, 5, 6]     # বর্তমান y = [1, 2, 3, 4, 5, 6]; x অপরিবর্তিত থাকে  

সাধারণত একটি করে উপাদান লিস্টে যোগ করার জন্য এই পদ্ধতি ব্যবহার করা হয়:

x = [1, 2, 3]  
x.append(0)           # বর্তমান x = [1, 2, 3, 0]  
y = x[-1]             # এর মান 0 হবে  
z = len(x)            # এর মান 4 হবে  

লিস্ট ডিকনস্ট্রাকশন

যদি আপনি জানেন যে লিস্টে কতগুলি উপাদান আছে, তাহলে খুব সহজে এই লিস্টটিকে ডিকনস্ট্রাক্ট করা যায়:

x, y = [1, 2]         # বর্তমান x = 1, y = 2  

যদি সমীকরণের উভয় পাশে উপাদানের সংখ্যা সমান না হয়, তাহলে আপনি একটি ValueError পাবেন। তাই আমরা প্রায়শই লিস্টের অবশিষ্ট অংশ সংরক্ষণের জন্য আন্ডারস্কোর (_) ব্যবহার করি:

_, y = [1, 2]         # বর্তমান y == 2, প্রথম উপাদানটি উপেক্ষা করা হয়  

টাপল (Tuples)

লিস্ট এবং টাপল অনেকটা একই রকম। লিস্টের সাথে টাপলের একমাত্র পার্থক্য হলো, টাপলের উপাদানগুলো পরিবর্তন করা যায় না।

টাপল তৈরি

আপনি প্রথম বন্ধনী (()) ব্যবহার করে অথবা কোনো বন্ধনী ছাড়াই টাপল তৈরি করতে পারেন:

my_tuple = (1, 2)  
other_tuple = 3, 4  
my_list = [1, 2]
my_list[1] = 3        # বর্তমান my_list হলো [1, 3]  
try:  
    my_tuple[1] = 3  
except TypeError:  
    print "টাপল পরিবর্তন করা যাবে না"  

ফাংশন থেকে একাধিক মান ফেরত পাওয়ার জন্য টাপল ব্যবহার করা খুব সুবিধাজনক:

def sum_and_product(x, y):  
    return (x + y),(x * y)  
sp = sum_and_product(2, 3)    # এর মান (5, 6) হবে  
s, p = sum_and_product(5, 10) # s = 15, p = 50  

টাপল (এবং লিস্ট) একাধিক উপাদানকে একসাথে অ্যাসাইন করা সমর্থন করে:

x, y = 1, 2       # বর্তমান x = 1, y = 2  
x, y = y, x       # পাইথনে দুটি ভ্যারিয়েবলের মান অদলবদল করা; বর্তমান x = 2, y = 1  

ডিকশনারি (Dictionaries)

ডিকশনারি তৈরি

পাইথনের আরেকটি মৌলিক ডেটা স্ট্রাকচার হলো ডিকশনারি। এটি আপনাকে কি (key) ব্যবহার করে দ্রুত সংশ্লিষ্ট ভ্যালু (value) পেতে সাহায্য করে:

empty_dict = {}                       # একটি খুবই পাইথনিক খালি ডিকশনারি সংজ্ঞা  
empty_dict2 = dict()                  # তেমন পাইথনিক নয় এমন একটি খালি ডিকশনারি সংজ্ঞা  
grades = { "Joel" : 80, "Tim" : 95 }  # ডিকশনারি স্টোরেজ  

ডিকশনারি উপাদান খোঁজা

আপনি স্কোয়ার ব্র্যাকেট এবং কি ব্যবহার করে সংশ্লিষ্ট ভ্যালু খুঁজতে পারেন:

joels_grade = grades["Joel"]          # এর মান 80 হবে  

যদি খোঁজা কি ডিকশনারিতে না থাকে, তাহলে একটি KeyError রিটার্ন করবে:

try:  
    kates_grade = grades["Kate"]  
except KeyError:  
    print "Kate এর জন্য কোনো গ্রেড নেই!"  

in ব্যবহার করে দেখা যায় যে কি ডিকশনারিতে আছে কিনা:

joel_has_grade = "Joel" in grades     # True  
kate_has_grade = "Kate" in grades     # False  

ডিকশনারির একটি পদ্ধতি আছে যা ডিফল্ট ভ্যালু প্রদান করে। যখন খোঁজা কি ডিকশনারিতে না থাকে, তখন এটি সেট করা ডিফল্ট ভ্যালু রিটার্ন করবে (কোনো এক্সেপশন তৈরি না করে):

joels_grade = grades.get("Joel", 0)   # এর মান 80 হবে  
kates_grade = grades.get("Kate", 0)   # এর মান 0 হবে  
no_ones_grade = grades.get("No One")  # ডিফল্ট ভ্যালু None রিটার্ন করবে  

ডিকশনারি পরিবর্তন

স্কোয়ার ব্র্যাকেট ব্যবহার করে ডিকশনারিতে কি-ভ্যালু পেয়ার তৈরি বা পরিবর্তন করা যায়:

grades["Tim"] = 99                    # পুরোনো মান প্রতিস্থাপন করা  
grades["Kate"] = 100                  # একটি কি-ভ্যালু পেয়ার যোগ করা  
num_students = len(grades)            # এর মান 3 হবে  

আমরা প্রায়শই ডেটা স্ট্রাকচার প্রকাশ করতে ডিকশনারি ব্যবহার করব, যেমন:

tweet = {  
    "user" : "joelgrus",  
    "text" : "Data Science is Awesome",  
    "retweet_count" : 100,  
    "hashtags" : ["#data", "#science", "#datascience", "#awesome", "#yolo"]  
}  

নির্দিষ্ট কি খোঁজা ছাড়াও, আমরা সমস্ত কি নিয়েও কাজ করতে পারি:

tweet_keys = tweet.keys()             # কি-এর একটি লিস্ট পাওয়া যায়  
tweet_values = tweet.values()         # ভ্যালু-এর একটি লিস্ট পাওয়া যায়  
tweet_items = tweet.items()           # (কি, ভ্যালু) টাপল পাওয়া যায়  
"user" in tweet_keys                  # True রিটার্ন করে, লিস্টে in ব্যবহার করে খোঁজা অদক্ষ  
"user" in tweet                       # আরও পাইথনিক ব্যবহার, ডিকশনারিতে in ব্যবহার করে দ্রুত খোঁজা  
"joelgrus" in tweet_values            # True  

ডিকশনারির কিগুলি অনন্য হয়, এবং লিস্টকে ডিকশনারির কি হিসেবে ব্যবহার করা যায় না। যদি আপনার একটি মাল্টি-পার্ট কি প্রয়োজন হয়, তাহলে আপনি টাপল ব্যবহার করতে পারেন, অথবা কোনো উপায়ে কিগুলোকে স্ট্রিং-এ রূপান্তর করতে পারেন।

DefaultDict

যদি আপনি একটি ডকুমেন্টে প্রতিটি শব্দের ফ্রিকোয়েন্সি গণনা করতে চান, তবে একটি সুস্পষ্ট উপায় হলো একটি ডিকশনারি তৈরি করা, যেখানে শব্দগুলো কি এবং তাদের ফ্রিকোয়েন্সি সংশ্লিষ্ট ভ্যালু হবে। তারপর ডকুমেন্টটি অতিক্রম করে, যদি কোনো শব্দ আগে দেখা গিয়ে থাকে, তাহলে ডিকশনারির সংশ্লিষ্ট কি-এর ভ্যালু 1 বাড়ানো হবে; আর যদি নতুন শব্দ হয়, তাহলে ডিকশনারিতে একটি নতুন কি-ভ্যালু পেয়ার যোগ করা হবে:

word_counts = {}  
for word in document:  
    if word in word_counts:  
        word_counts[word] += 1  
    else:  
        word_counts[word] = 1  

অবশ্যই, আপনি এভাবে “আগে কাজ, পরে চিন্তা” পদ্ধতিতে একটি অনুপস্থিত কি আগে থেকেই হ্যান্ডেল করতে পারেন:

word_counts = {}  
for word in document:  
    try:  
        word_counts[word] += 1  
    except KeyError:  
        word_counts[word] = 1  

তৃতীয় পদ্ধতিটি হলো get ব্যবহার করা, এই পদ্ধতি অনুপস্থিত কি হ্যান্ডেল করার ক্ষেত্রে চমৎকার কাজ করে:

word_counts = {}  
for word in document:  
    previous_count = word_counts.get(word, 0)  
    word_counts[word] = previous_count + 1  

বিল্ট-ইন defaultdict সাধারণ ডিকশনারির মতোই, একমাত্র পার্থক্য হলো, যখন আপনি ডিকশনারিতে একটি অনুপস্থিত কি খুঁজতে চেষ্টা করেন, তখন defaultdict আপনার সরবরাহ করা কি ব্যবহার করে স্বয়ংক্রিয়ভাবে একটি কি-ভ্যালু পেয়ার তৈরি করে। defaultdict ব্যবহার করার জন্য আপনাকে collections লাইব্রেরি ইম্পোর্ট করতে হবে:

from collections import defaultdict  
word_counts = defaultdict(int)        # int() 0 তৈরি করে  
for word in document:  
    word_counts[word] += 1  

লিস্ট, সাধারণ ডিকশনারি এমনকি কাস্টম ফাংশনের ক্ষেত্রেও defaultdict খুব কার্যকর:

dd_list = defaultdict(list)           # list() একটি খালি লিস্ট তৈরি করে  
dd_list[2].append(1)                  # বর্তমান dd_list হলো {2: [1]}  
dd_dict = defaultdict(dict)           # dict() একটি খালি ডিকশনারি তৈরি করে  
dd_dict["Joel"]["City"] = "Seattle"   # বর্তমান dd_dict এর বিষয়বস্তু হলো { "Joel" : { "City" : Seattle"}}  
dd_pair = defaultdict(lambda: [0, 0]) # একটি ডিকশনারি তৈরি করে যেখানে কি-এর সংশ্লিষ্ট ভ্যালু হলো একটি লিস্ট  
dd_pair[2][1] = 1                     # বর্তমান dd_pair এর বিষয়বস্তু হলো {2: [0,1]}  

এই পদ্ধতিটি খুব দরকারী, ভবিষ্যতে যখন আমরা ডিকশনারি থেকে নির্দিষ্ট কি-এর ভ্যালু পেতে চাইব, তখন আর কি বিদ্যমান আছে কিনা তা পরীক্ষা করার প্রয়োজন হবে না।

কাউন্টার (Counter)

কাউন্টার সরাসরি একগুচ্ছ মানকে ডিকশনারি-সদৃশ বস্তুতে রূপান্তর করতে পারে, যেখানে কি হলো সেই গুচ্ছের একটি উপাদান এবং সংশ্লিষ্ট ভ্যালু হলো সেই উপাদানটি কতবার এসেছে তার সংখ্যা। এটি হিস্টোগ্রাম তৈরি করার সময় প্রায়শই ব্যবহৃত হয়:

from collections import Counter  
c = Counter([0, 1, 2, 0]) # c (মোটামুটি) হলো { 0 : 2, 1 : 1, 2 : 1 }  

এভাবে আমরা শব্দ ফ্রিকোয়েন্সি গণনা করার একটি খুব সহজ পদ্ধতি পাই:

word_counts = Counter(document)  

কাউন্টারের আরেকটি খুব সাধারণ পদ্ধতি হলো most_common, যা সরাসরি সর্বাধিক ফ্রিকোয়েন্সির কয়েকটি শব্দ এবং তাদের ফ্রিকোয়েন্সি প্রদান করে:

# শীর্ষ 10টি সর্বাধিক ফ্রিকোয়েন্সির শব্দ এবং তাদের গণনা আউটপুট করুন  
for word, count in word_counts.most_common(10):  
    print word, count  

সেট (Sets)

পাইথনের আরেকটি ডেটা স্ট্রাকচার হলো সেট। সেট হলো বিভিন্ন উপাদানের একটি সংগ্রহ।
এভাবে একটি সেট তৈরি করে তাতে উপাদান যোগ করা যায়:

s = set()  
s.add(1)          # s হলো { 1 }  
s.add(2)          # s হলো { 1, 2 }  
s.add(2)          # s হলো { 1, 2 }  
x = len(s)        # এর মান 2 হবে  
y = 2 in s        # এর মান True হবে  
z = 3 in s        # এর মান False হবে  

সেট ব্যবহারের দুটি প্রধান কারণ:

প্রথমত, সেটের in অপারেশন অত্যন্ত কার্যকর। যখন একটি ডেটাসেটের উপাদানের সংখ্যা খুব বেশি হয়, তখন লিস্টের চেয়ে সেট আকারে উপাদান খোঁজা অনেক বেশি উপযুক্ত:

stopwords_list = ["a","an","at"] + hundreds_of_other_words + ["yet", "you"]  
"zip" in stopwords_list               # অদক্ষ, প্রতিটি উপাদান পরীক্ষা করতে হয়  
stopwords_set = set(stopwords_list)  
"zip" in stopwords_set                # খোঁজা সফল এবং দ্রুত  

দ্বিতীয়ত, একগুচ্ছ ডেটার মধ্যে অনন্য উপাদানগুলো পেতে সেট ব্যবহার করা খুব সুবিধাজনক:

item_list = [1, 2, 3, 1, 2, 3]  
num_items = len(item_list)            # 6  
item_set = set(item_list)             # {1, 2, 3}  
num_distinct_items = len(item_set)    # 3  
distinct_item_list = list(item_set)   # [1, 2, 3]  

তবে বাস্তবে, সেট ডিকশনারি এবং লিস্টের চেয়ে কম ব্যবহৃত হয়।

শর্তাধীন স্টেটমেন্ট

বেশিরভাগ প্রোগ্রামিং ভাষাতেই, আপনি if ব্যবহার করে শর্তাধীন শাখা তৈরি করতে পারেন, যেমন:

if 1 > 2:  
    message = "যদি 1 দুই এর চেয়ে বড় হতো…"  
elif 1 > 3:  
    message = "elif মানে 'else if'"  
else:  
    message = "যখন আর কোনো উপায় থাকে না, তখন else ব্যবহার করুন (যদি চান)"  

আপনি চাইলে শর্তাধীন স্টেটমেন্টগুলো এক লাইনেও লিখতে পারেন, তবে এটি খুব কম ব্যবহৃত হয়:

parity = "even" if x % 2 == 0 else "odd"  

লুপ স্টেটমেন্ট

while লুপ

পাইথনে while লুপ:

x = 0  
while x < 10:  
    print x, "10 এর চেয়ে ছোট"  
    x += 1  

for লুপ

for-in লুপ বেশি ব্যবহৃত হয়:

for x in range(10):  
    print x, "10 এর চেয়ে ছোট"  

আরও জটিল লজিক্যাল এক্সপ্রেশনের জন্য continue এবং break স্টেটমেন্ট ব্যবহার করা যায়:

for x in range(10):  
    if x == 3:  
        continue          # সরাসরি পরবর্তী লুপে চলে যায়  
    if x == 5:  
        break             # লুপ থেকে সম্পূর্ণরূপে বেরিয়ে আসে  
    print x  

ফলাফল হবে 0, 1, 2 এবং 4।

ট্রুথিনেস (Truthiness)

পাইথনে বুলিয়ান ভ্যারিয়েবলগুলো অন্যান্য ভাষার মতোই ব্যবহৃত হয়, একমাত্র পার্থক্য হলো প্রথম অক্ষর অবশ্যই বড় হাতের হতে হবে:

one_is_less_than_two = 1 < 2      # True হবে  
true_equals_false = True == False # False হবে  

পাইথন None ব্যবহার করে বোঝায় যে একটি ভ্যালু অনুপস্থিত, যা অন্যান্য ভাষার null এর মতো:

x = None  
print x == None        # True আউটপুট দেবে, তবে এটি ততটা পরিপাটি নয়  
print x is None        # True আউটপুট দেবে, এটি আরও পরিপাটি  

পাইথন আপনাকে বুলিয়ান মানের পরিবর্তে অন্যান্য মান ব্যবহার করার অনুমতি দেয়। নিম্নলিখিত সবগুলি False এর সমতুল্য:

একইভাবে, অনেক True এর সমতুল্য মানও আছে, যা আপনাকে খালি লিস্ট, খালি স্ট্রিং এবং খালি ডিকশনারি ইত্যাদি পরীক্ষা করতে খুব সুবিধা দেয়।

অবশ্যই, আপনি যদি ফলাফল অনুমান করতে না পারেন, তাহলে ব্যবহারের সময় ভুল হতে পারে:

s = some_function_that_returns_a_string()  
if s:  
    first_char = s[0]  
else:  
    first_char = ""  

একটি আরও সরল পদ্ধতি, যা উপরের পদ্ধতির সমান কাজ করে:

first_char = s and s[0]  

যদি প্রথম ভ্যালুটি সত্য (True) হয়, তাহলে দ্বিতীয় ভ্যালুটি রিটার্ন করবে, অন্যথায় প্রথম ভ্যালুটি রিটার্ন করবে।

একইভাবে, যদি x একটি সংখ্যা হতে পারে বা খালি হতে পারে, তাহলে এভাবে আপনি একটি নিশ্চিত সংখ্যা x পেতে পারেন:

safe_x = x or 0  

পাইথনে আরও একটি all ফাংশন আছে, যা প্রতিটি উপাদান True হলে True রিটার্ন করে। any ফাংশন, যা শুধুমাত্র একটি উপাদান True হলেই True রিটার্ন করে। উদাহরণস্বরূপ, যদি একটি লিস্টের প্রতিটি উপাদানই “সত্য” হয়, তাহলে all ফাংশন True রিটার্ন করবে, অন্যথায় False রিটার্ন করবে:

all([True, 1, { 3 }])       # True  
all([True, 1, {}])          # False, {} 'False' এর সমতুল্য  
any([True, 1, {}])          # True  
all([])                     # True, 'False' এর সমতুল্য কোনো উপাদান নেই  
any([])                     # False, 'True' এর সমতুল্য কোনো উপাদান নেই  

আরও পড়ুন:
ডেটা সায়েন্সে ব্যবহৃত পাইথনের সাধারণ সিনট্যাক্স (উন্নত)