Python වල map(), filter(), reduce() – දත්ත හසුරුවන ක්‍රම. Data Manipulation with Python SC Guide

Python වල map(), filter(), reduce() – දත්ත හසුරුවන ක්‍රම. Data Manipulation with Python SC Guide

කොහොමද යාලුවනේ! Python වල Data Manipulation වලට අත්‍යවශ්‍ය Tools ටිකක් ගැන කතා කරමු: map(), filter(), reduce()

අද අපි කතා කරන්නේ Python වල data manipulation වලට නැතුවම බැරි, ගොඩක් වැදගත් Concepts ටිකක් ගැන. මේවා හරියට Tools වගයක් වගේ, අපේ Code එක Functional විදියට ලියන්න උදව් වෙනවා. ඒ කියන්නේ, අපිට ලොකු Code Blocks ගොඩක් නැතුව, Cleaner, Readable Code එකක් ලියන්න මේවා උපකාරී වෙනවා. අද අපි මූලිකවම අවධානය යොමු කරන්නේ map(), filter(), සහ reduce() කියන මේ සුපිරි Functional Trio එක ගැන.

ඔයාගේ Python Code එක තවත් Powerful කරන්න මේ functions කොහොමද පාවිච්චි කරන්නේ කියලා බලමු. මේවා ගැන හොඳ අවබෝධයක් තියෙනවා නම්, ඔයාට Data Sets එක්ක වැඩ කරනකොට වෙලාව ඉතුරු කරගන්නත්, ඔයාගේ Code එක Maintain කරන්න ලේසි වෙන්නත් උපකාරී වෙනවා. එහෙනම්, අපි පටන් ගමු!

1. map(): දත්ත හැඩගැන්වීම (Data Transformation)

map() කියන්නේ Python වල තියෙන භාණ්ඩයක් වගේ. මේකේ ප්‍රධාන වැඩේ තමයි, Iterable එකක (ඒ කියන්නේ List එකක්, Tuple එකක්, String එකක් වගේ) තියෙන හැම Element එකකටම අපි දෙන Function එක Apply කරලා අලුත් Iterable එකක් හදන එක. මේක හරියට Factory එකක Production Line එකක් වගේ. අමුද්‍රව්‍යයක් ඇතුල් කලාම, ඒක එකම විදියට Transform කරලා අලුත් භාණ්ඩයක් විදියට එළියට එනවා වගේ තමයි map() වැඩ කරන්නේ.

map() Syntax:

map(function, iterable)
  • function: මේක තමයි හැම Element එකකටම Apply කරන්න ඕන Function එක.
  • iterable: මේක තමයි අපිට Transform කරන්න ඕන Data Set එක.

map() එක Return කරන්නේ Map Object එකක්. මේක Iterator එකක් නිසා, අපිට අවශ්‍ය නම් list(), tuple() වගේ Constructor එකක් පාවිච්චි කරලා List එකක් විදියට Convert කරගන්න පුළුවන්.

උදාහරණ 1: සංඛ්‍යා වර්ග කිරීම (Squaring Numbers)

අපි හිතමු අපිට Numbers List එකක් තියෙනවා කියලා. ඒ List එකේ තියෙන හැම Number එකක්ම Square කරන්න ඕන නම්, map() පාවිච්චි කරන්නේ මෙහෙමයි:

numbers = [1, 2, 3, 4, 5]

# Function එකක් නිර්වචනය කරමු
def square(num):
    return num * num

# map() භාවිතා කරමු
squared_numbers_map = map(square, numbers)

# ප්‍රතිඵලය බලන්න List එකකට convert කරමු
print(list(squared_numbers_map))
# Output: [1, 4, 9, 16, 25]

මේකේදී square කියන Function එක numbers කියන List එකේ හැම Element එකකටම Apply වෙලා, අලුත් Squared Numbers List එකක් හදනවා. ගොඩක් Simple නේද?

උදාහරණ 2: නම් Uppercase වලට වෙනස් කිරීම (Converting Names to Uppercase)

දැන් අපි බලමු String List එකක් Uppercase වලට Convert කරන්නේ කොහොමද කියලා.

names = ["kasun", "nuwan", "chamara", "saman"]

# Lambda Function එකක් භාවිතා කරමු
uppercased_names_map = map(lambda name: name.upper(), names)

print(list(uppercased_names_map))
# Output: ['KASUN', 'NUWAN', 'CHAMARA', 'SAMAN']

මෙතනදී අපි lambda Function එකක් පාවිච්චි කලා. lambda Functions කියන්නේ පොඩි, Anonymous Functions. මේවා එක පාරක් විතරක් පාවිච්චි කරන Functions වලට ගොඩක් පහසුයි. map() එක්ක lambda පාවිච්චි කරන එක ගොඩක්ම ජනප්‍රියයි, මොකද Code එක ගොඩක් කෙටි වෙනවා.

map() ගොඩක්ම හොඳයි, අපි ලොකු Data Sets එක්ක වැඩ කරනකොට. මොකද මේක Lazy Evaluation එකක් කරන නිසා, එකපාරටම Memory එකට whole List එකක් Load වෙන්නේ නැහැ. අවශ්‍ය වෙලාවට විතරයි Element එකෙන් Element එක Process කරන්නේ.

2. filter(): දත්ත තෝරාගැනීම (Data Selection)

filter() කියන්නේ map() වගේම තවත් වැදගත් Functional Programming tool එකක්. filter() එකේ ප්‍රධාන වැඩේ තමයි Iterable එකකින් අපිට අවශ්‍ය Elements විතරක් තෝරාගන්න එක. මේක හරියට වැලි ගොඩක් පෙරලා, වටිනා ගල් කැට විතරක් අහුලනවා වගේ වැඩක්. අපි දෙන Condition එක True වෙන Elements විතරක් තමයි filter() එකේ ප්‍රතිඵලයක් විදියට එන්නේ.

filter() Syntax:

filter(function, iterable)
  • function: මේක Predicate Function එකක් වෙන්න ඕන. ඒ කියන්නේ True නැත්නම් False Return කරන Function එකක්.
  • iterable: මේක තමයි අපිට Filter කරන්න ඕන Data Set එක.

filter() එකත් Return කරන්නේ Filter Object එකක්. ඒකත් Iterator එකක් නිසා, අවශ්‍ය නම් list(), tuple() වගේ Constructor එකක් පාවිච්චි කරලා List එකක් විදියට Convert කරගන්න පුළුවන්.

උදාහරණ 1: ඔත්තේ සංඛ්‍යා පෙරීම (Filtering Odd Numbers)

අපි හිතමු අපිට Numbers List එකකින් Odd Numbers විතරක් තෝරාගන්න ඕන කියලා.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Odd Numbers තෝරන්න Function එකක් ලියමු
def is_odd(num):
    return num % 2 != 0

# filter() භාවිතා කරමු
odd_numbers_filter = filter(is_odd, numbers)

# ප්‍රතිඵලය බලන්න List එකකට convert කරමු
print(list(odd_numbers_filter))
# Output: [1, 3, 5, 7, 9]

මෙතනදී is_odd කියන Function එක numbers List එකේ හැම Element එකකටම Apply වෙලා, Odd Numbers විතරක් Filter කරලා දෙනවා.

උදාහරණ 2: නිශ්චිත අකුරකින් පටන් ගන්නා නම් තෝරාගැනීම (Filtering Names Starting with a Specific Letter)

දැන් අපි බලමු 'A' අකුරෙන් පටන් ගන්න Names විතරක් Select කරන්නේ කොහොමද කියලා.

names = ["Amal", "Bhathiya", "Anusha", "Kamal", "Aruni"]

# 'A' අකුරෙන් පටන් ගන්න නම් තෝරන්න Lambda Function එකක් භාවිතා කරමු
filtered_names_filter = filter(lambda name: name.startswith('A'), names)

print(list(filtered_names_filter))
# Output: ['Amal', 'Anusha', 'Aruni']

filter() එකත් map() වගේම Lazy Evaluation කරන නිසා, ලොකු Data Sets එක්ක වැඩ කරනකොට Memory Efficient වෙනවා. මේක Data Validation, Data Cleaning වගේ වැඩ වලට ගොඩක් ප්‍රයෝජනවත්.

3. reduce(): දත්ත එකතු කිරීම (Data Aggregation)

reduce() කියන්නේ map() සහ filter() වලට වඩා ටිකක් වෙනස්, නමුත් ඒ වගේම බලවත් Tool එකක්. මේක තියෙන්නේ Python වල Built-in Functions අතර නෙවෙයි, functools Module එකේ. ඒ නිසා, මේක පාවිච්චි කරන්න නම් මුලින්ම Import කරගන්න ඕන.

reduce() එකේ ප්‍රධාන වැඩේ තමයි Iterable එකක තියෙන Elements එකිනෙකාට Combine කරලා, තනි Final Value එකක් හදන එක. මේක හරියට අපි ගණන් කරනකොට එකතු කරගෙන, අන්තිමට එක උත්තරයක් ගන්නවා වගේ.

reduce() Syntax:

from functools import reduce

reduce(function, iterable, initializer)
  • function: මේක Argument දෙකක් ගන්න Function එකක් වෙන්න ඕන. (accumulator, current_value)
  • iterable: මේක තමයි අපිට Reduce කරන්න ඕන Data Set එක.
  • initializer (optional): මේක තමයි මුලින්ම accumulator එකට දෙන Value එක. මේක නොදුන්නොත්, Iterable එකේ පළවෙනි Element එක Initial Value එක විදියට ගන්නවා.

reduce() එක Return කරන්නේ Single Value එකක්.

උදාහරණ 1: සංඛ්‍යා එකතු කිරීම (Summing Numbers)

අපි හිතමු Numbers List එකක එකතුව හොයන්න ඕන කියලා.

from functools import reduce

numbers = [1, 2, 3, 4, 5]

# සංඛ්‍යා දෙකක් එකතු කරන්න Function එකක් ලියමු
def add(x, y):
    return x + y

# reduce() භාවිතා කරමු
sum_of_numbers = reduce(add, numbers)

print(sum_of_numbers)
# Output: 15 (1+2+3+4+5)

මේකේදී මුලින්ම add(1, 2) වෙනවා, ඒකෙන් එන 3ට ඊළඟ Element එක (3) එකතු වෙනවා, ඒකෙන් එන 6ට ඊළඟ Element එක (4) එකතු වෙනවා. මේ විදියට List එකේ හැම Element එකක්ම Combine වෙලා අන්තිමට තනි Value එකක් දෙනවා.

උදාහරණ 2: ලොකුම සංඛ්‍යාව සොයාගැනීම (Finding the Maximum Number)

List එකක තියෙන ලොකුම Number එක හොයන්නත් reduce() පාවිච්චි කරන්න පුළුවන්.

from functools import reduce

numbers = [12, 5, 23, 8, 17]

# ලොකුම සංඛ්‍යාව හොයන්න Lambda Function එකක් භාවිතා කරමු
max_number = reduce(lambda x, y: x if x > y else y, numbers)

print(max_number)
# Output: 23

මේකේදී, lambda x, y: x if x > y else y කියන Function එක හැම පාරම Arguments දෙකෙන් ලොකු එක Return කරනවා. අන්තිමට List එකේ තියෙන ලොකුම Number එක අපිට ලැබෙනවා.

reduce() එක ගොඩක්ම ප්‍රයෝජනවත් වෙන්නේ Data Aggregation, String Concatenation, හෝ Complex Calculations වගේ අවස්ථා වලදී. ඒත් මතක තියාගන්න, reduce() පාවිච්චි කරන හැම තැනකම Looping Structure එකක් (for loop) පාවිච්චි කරන්නත් පුළුවන්. සමහර වෙලාවට For Loop එකක් reduce() එකකට වඩා කියවන්න පහසු වෙන්න පුළුවන්.

4. Comprehensions vs. map()/filter(): කවදාද මොනවාද පාවිච්චි කරන්නේ?

Python වල map() සහ filter() වලට හොඳ Alternative එකක් තමයි Comprehensions (List Comprehensions, Dictionary Comprehensions, Set Comprehensions). මේවා ගොඩක්ම Pythonic විදියට Simple Data Transformations සහ Filtering කරන්න උදව් වෙනවා. එහෙනම්, අපි බලමු කවදාද මොනවාද පාවිච්චි කරන්නේ කියලා.

List Comprehension vs. map()

Simple Transformations වලදී List Comprehensions ගොඩක් වෙලාවට වඩා Readability වැඩි වෙනවා. Code එක කෙටි වෙලා, මොකක්ද වෙන්නේ කියලා තේරුම් ගන්න ලේසි වෙනවා.

map() උදාහරණය:

numbers = [1, 2, 3, 4, 5]
squared_numbers_map = list(map(lambda x: x*x, numbers))
print(squared_numbers_map)
# Output: [1, 4, 9, 16, 25]

List Comprehension උදාහරණය:

numbers = [1, 2, 3, 4, 5]
squared_numbers_comprehension = [x*x for x in numbers]
print(squared_numbers_comprehension)
# Output: [1, 4, 9, 16, 25]

මේ උදාහරණ දෙකම එකම ප්‍රතිඵලය දෙනවා. ඒත් List Comprehension එකක් කියවන්න ගොඩක් පහසුයි නේද? [x*x for x in numbers] කියන එකෙන් කියවෙන්නේ, "numbers වල තියෙන හැම x එකක්ම square කරලා අලුත් List එකක් හදන්න" කියන එක.

List Comprehension vs. filter()

Simple Filtering වලදීත් List Comprehensions ගොඩක් පහසුවෙන් පාවිච්චි කරන්න පුළුවන්.

filter() උදාහරණය:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers_filter = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers_filter)
# Output: [2, 4, 6, 8, 10]

List Comprehension උදාහරණය:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers_comprehension = [x for x in numbers if x % 2 == 0]
print(even_numbers_comprehension)
# Output: [2, 4, 6, 8, 10]

මේකත් List Comprehension එකකින් කියවන්න පහසුයි. [x for x in numbers if x % 2 == 0] කියන්නේ, "numbers වල තියෙන හැම x එකක්ම ගන්න, හැබැයි x % 2 == 0 නම් විතරයි" කියන එක.

කවදාද මොනවාද පාවිච්චි කරන්නේ?

  • Comprehensions (List, Dict, Set):
    • පහසු අවස්ථා: Transformation එක හෝ Filtering Condition එක Simple නම්, Comprehensions ගොඩක්ම හොඳයි. Code එක කෙටි සහ Readability වැඩි වෙනවා.
    • ප්‍රතිඵලය List එකක්/Set එකක්/Dictionary එකක් නම්: මේවා කෙලින්ම Data Structure එකක් Return කරන නිසා, ගොඩක් අවස්ථා වලදී වඩාත් පහසුයි.
    • Performance: Simple Operations වලදී Comprehensions සාමාන්‍යයෙන් map()/filter() වලට වඩා ටිකක් වේගවත් වෙනවා, මොකද මේවා Python Interpreter එක මට්ටමින් Optimize වෙලා තියෙනවා.
  • map() සහ filter():
    • සංකීර්ණ Functions: ඔයාට Apply කරන්න ඕන Function එක දැනටමත් වෙන තැනක Define කරලා තියෙනවා නම්, නැත්නම් ඒක Complex Logic එකක් නම්, map()/filter() පාවිච්චි කරන එක හොඳයි.
    • Lazy Evaluation: ඔයා ගොඩක් ලොකු Data Sets එක්ක වැඩ කරනවා නම්, සහ එකපාරටම Memory එකට whole List එකක් Load කරගන්න අවශ්‍ය නැත්නම්, map() සහ filter() Iterator Objects Return කරන නිසා Memory Efficient වෙනවා. මේවා Element එකෙන් Element එක Process කරන නිසා ලොකු Data Sets වලට ගොඩක් හොඳයි.
    • Functional Chaining: සමහර අවස්ථා වලදී, map() සහ filter() එකින් එකට Chain කරලා Complex Data Pipelines හදන්න පුළුවන්.

සාරාංශයක් විදියට කිව්වොත්, Code එක Simple නම්, කෙටි නම්, Comprehensions පාවිච්චි කරන්න. Function එක Complex නම්, නැත්නම් Memory Efficiency ගැන හිතනවා නම්, map()/filter() පාවිච්චි කරන්න. ඒත් මතක තියාගන්න, හොඳම දේ තමයි ඔයාගේ Code එක කියවන අයට තේරෙන විදියට ලියන එක!

5. Best Practices and Tips: හොඳම පුරුදු සහ උපදෙස්

දැන් අපි මේ functions තුන ගැන හොඳටම දන්නවා. එහෙනම්, මේවා පාවිච්චි කරනකොට මතක තියාගන්න ඕන Tips ටිකක් බලමු.

When Not to Use (භාවිතා නොකළ යුත්තේ කවදාද)

සමහර අවස්ථා වලදී, Simple for loops වඩා හොඳයි. විශේෂයෙන්ම, ඔයාගේ Operation එක Side Effects (Variable එකක් modify කරනවා වගේ) ඇති කරනවා නම්, නැත්නම් Operation එකේ අරමුණ Transformations හෝ Filtering වලට වඩා වෙනස් නම්, for loop එකක් පාවිච්චි කරන එක Code එකට පැහැදිලි බවක් දෙනවා.

Performance Considerations (කාර්ය සාධනය)

ලොකු Data Sets එක්ක වැඩ කරනකොට, map() සහ filter() වල Lazy Evaluation එක ගොඩක් වාසියි. මේවා Memory එක ගොඩක් කා දමන්නේ නැහැ. Comprehensions නම් එකපාරටම whole List එකක් Memory එකට Load කරනවා. ඒ නිසා, ඔයාගේ Application එකේ Performance ගැන හිතනවා නම්, මේක වැදගත්.

Return Types (ප්‍රතිලාභ වර්ග)

map() සහ filter() Return කරන්නේ Iterator Objects. මේවා direct List එකක් නෙවෙයි. ඒ නිසා, ඔයාට List එකක් අවශ්‍ය නම්, list() Constructor එක පාවිච්චි කරන්න අමතක කරන්න එපා. reduce() නම් Return කරන්නේ Single Value එකක්.

# map() and filter() return iterators
my_map_object = map(lambda x: x*2, [1,2,3])
my_filter_object = filter(lambda x: x > 1, [1,2,3])

print(type(my_map_object))    # <class 'map'>
print(type(my_filter_object)) # <class 'filter'>

# To get a list:
print(list(my_map_object))
print(list(my_filter_object))

Lambda Functions (ලැම්ඩා ෆන්ෂන්ස්)

උදාහරණ වලදී දැක්කා වගේ, lambda Functions කියන්නේ map(), filter(), reduce() එක්ක ගොඩක් හොඳට වැඩ කරන පොඩි, Single-line Functions. හැබැයි මේවා ගොඩක් Complex කරන්න එපා. Complex Logic එකක් තියෙනවා නම්, වෙනම def keyword එකෙන් Function එකක් Define කරන එක තමයි හොඳම පුරුද්ද.

Readability (කියවීමට පහසුව)

ඔයාගේ Code එක තව කෙනෙක්ට, නැත්නම් ඔයාටම පස්සේ කාලෙක බලනකොට තේරෙන්න ඕන. map(), filter(), reduce() පාවිච්චි කරනකොට සමහර වෙලාවට Code එක ගොඩක් කෙටි වෙන නිසා කියවන්න අමාරු වෙන්න පුළුවන්, විශේෂයෙන්ම Nested Lambda Functions පාවිච්චි කරනකොට. ඒ නිසා, Simple Operations වලට Comprehensions පාවිච්චි කරන එක හොඳයි. Complex Operations වලට වෙනම Function එකක් Define කරලා map()/filter() වලට දෙන එක Code එක Cleaner කරනවා.

අවසාන වශයෙන්...

ඉතින් යාලුවනේ, ඔයාලට දැන් Python වල map(), filter(), සහ reduce() කියන බලවත් Tools තුන ගැන හොඳ අවබෝධයක් ලැබිලා ඇති කියලා හිතනවා. මේවා Functional Programming Concept වල අත්‍යවශ්‍ය කොටස්. මේවා හරියට පාවිච්චි කරන එකෙන් ඔයාගේ Python Code එක ගොඩක් Cleaner, More Efficient, සහ Maintainable කරන්න පුළුවන්.

මතක තියාගන්න, Software Development වලදී එකම ප්‍රශ්නයකට විසඳුම් ගොඩක් තියෙන්න පුළුවන්. වැදගත්ම දේ තමයි, ඔයාගේ Project එකට, ඔයාගේ Team එකට, සහ ඔයාගේ Data Set එකට ගැලපෙන හොඳම Solution එක තෝරාගන්න එක. අද අපි කතා කරපු Concepts ඔයාගේ දිනපතා Coding Life එකට Implement කරලා බලන්න. Practice කරන තරමට ඔයා මේවාට Expert කෙනෙක් වේවි!

මේ Article එක ගැන ඔයාගේ අදහස්, ප්‍රශ්න, නැත්නම් ඔයාට මේවා පාවිච්චි කරපු Experience එකක් තියෙනවා නම්, පහලින් Comment කරන්න අමතක කරන්න එපා. අපි තවත් අලුත් Technical Concept එකක් එක්ක ඉක්මනටම හම්බවෙමු. එහෙනම්, හැමෝටම ජය වේවා! Happy Coding!