Lập trình Hàm với ví dụ PYTHON

Ngày đăng: 29/11/2019   -    Cập nhật: 20/11/2020
Lập trình hàm (Functional Programming) là một khái niệm, mô hình lập trình thú vị được chú ý nhiều gần đây.


Lập trình Hàm với ví dụ Python

Lập trình Hàm với ví dụ Python

 

Bài viết này trình bày một số khía cạnh quan trọng nhất của Lập trình hàm nói chung qua các Ví dụ Lập trình hàm trong Python.




Lập trình hàm là một loại mô hình lập trình mà các hàm biểu diễn quan hệ giữa các đối tượng, giống như trong toán học.


Vì vậy, bạn sẽ thấy các hàm (functions) xuất hiện nhiều đáng kể.


Mô hình lập trình này có thể được thực hiện bằng nhiều ngôn ngữ. Có một số ngôn ngữ sinh ra đã dựa theo mô hình lập trình hàm như Closure, Erlang hoặc Haskel.


Nhưng cũng có nhiều ngôn ngữ khác cũng hỗ trợ lập trình hàm như: C ++, C#, F#, Java, Python, JavaScript và các ngôn ngữ khác.



TỰ HỌC LẬP TRÌNH JAVA nếu như bạn yêu thích nó!


Trong bài viết này, bạn sẽ tìm thấy giải thích về một số nguyên tắckhái niệm quan trọng liên quan đến Lập trình Hàm và sử dụng ngôn ngữ Python:


  • pure functions
  • anonymous functions
  • recursive functions
  • first-class functions
  • immutable data types.


1. Prue functions là gì?



Prue funtions là một hàm thuần túy:


  • Hàm bình thường: Trả về cùng một kết quả nếu cung cấp cùng một đối số
  • Không có tác dụng khác.


Nếu như một hàm sử dụng một đối tượng từ phạm vi cao hơn hoặc số ngẫu nhiên, giao tiếp với các tệp, v.v., nó có thể không thuần túy vì kết quả của nó không chỉ phụ thuộc vào các đối số của nó.


Một hàm sửa đổi các đối tượng bên ngoài phạm vi của nó, ghi vào tệp, in ra console, v.v., có tác dụng khác cũng có thể không thuần túy.


Các hàm thuần túy thường không sử dụng các đối tượng từ các phạm vi bên ngoài và do đó tránh các trạng thái chia sẻ.


Điều này có thể đơn giản hóa một chương trình và giúp thoát khỏi một số lỗi.



2. Anonymous Functions là gì?




Các hàm ẩn danh (Anonymous Funtion hay còn được gọi là lambda) có thể rất thuận tiện cho các cấu trúc lập trình hàm.


Chúng không có tên và thường được tạo ra với một mục đích duy nhất.


Trong Python, bạn tạo một hàm ẩn danh với từ khóa lambda:



lambda x, y: x + y


Câu lệnh trên tạo ra hàm chấp nhận hai đối số và trả về tổng của chúng.


Trong ví dụ tiếp theo (chạy trên terminal), các hàm fg thực hiện cùng một việc:



>>> f = lambda x, y: x + y
>>> def g(x, y):
return x + y


Nếu bạn chạy trên Editor / hoặc IDE thì bạn có thể viết như sau:



        # Khai báo hàm lambda
        f = lambda xyx + y

        # Khai báo hàm thông thường
        def g(xy):
            return x + y

        # Gọi hàm
        print(f(34))
        print(g(34))
 


3. Recursive Functions

 

Recursive Functions (Hay còn được gọi là Hàm đệ quy) là một hàm tự gọi chính nó trong quá trình thực thi.


Nếu bạn mới nghe đệ quy lần đầu thì bạn có thể xem hình ảnh minh họa sau:



Minh họa về hàm đệ quy (Recursive Function)

Minh họa về hàm đệ quy (Recursive Function)


Ví dụ: Chúng ta có thể sử dụng đệ quy để tìm giai thừa theo kiểu lập trình hàm:


>>> def factorial_r(n):
if n == 0:
return 1
return n * factorial_r(n - 1)


Ngoài ra, chúng ta có thể giải quyết vấn đề tương tự bằng cách sử dụng vòng lặp trong Python (for hoặc while):


>>> def factorial_l(n):
if n == 0:
return 1
product = 1
for i in range(1, n+1):
product *= i
return product


4. First Class Functions



Trong lập trình hàm, các hàm là các first-class object, còn được gọi là các hàm bậc cao hơn (high-order functions) - Các kiểu dữ liệu được xử lý giống như các kiểu khác.


Các hàm (hoặc, chính xác hơn, các con trỏ hoặc tham chiếu của chúng) có thể được truyền dưới dạng đối số và được trả về từ các hàm khác.


Chúng cũng có thể được sử dụng như các biến trong các chương trình.


Đoạn mã dưới đây minh họa việc truyền hàm max (built-in function) dưới dạng đối số của hàm f và gọi nó từ bên trong f.



>>> def f(function, *arguments):
return function(*arguments)

>>> f(max, 1, 2, 4, 8, 16)
16


Các Khái niệm lập trình hàm rất quan trọng là:

  • mapping
  • filtering
  • reducing


Chúng đều được hỗ trợ trong Python.


4.1. Mapping



Mapping được thực hiện với class map được tích hợp sẵn (built-in class).


Nó lấy một hàm (hoặc phương thức hoặc bất kỳ thứ gì có thể gọi) làm đối số thứ nhất và iterable (như list hoặc tuple) làm đối số thứ hai và trả về iterator với kết quả gọi hàm trên các item của iterable.



Iterable object là một đối tượng sau khi sử dụng các phương thức sẽ trả về một iterator, ví dụ như Chuỗi, List, Tuple.


Tham khảo: List trong Python và Tuple trong Python

 

Iterator là các đối tượng cho phép ta lấy từng phần tử của nó, hành động này có thể được lặp đi lặp lại.


>>> list(map(abs, [-2, -1, 0, 1, 2]))
[2, 1, 0, 1, 2]


Trong ví dụ này, hàm abs (built-in function) được gọi với các đối số -2, -1, 0, 1 và 2, tương ứng.


Chúng ta có thể có được kết quả tương tự với kỹ thuật comprehension như sau:



>>> [abs(item) for item in [-2, -1, 0, 1, 2]]
[2, 1, 0, 1, 2]


Chúng ta cũng có thể không phải sử dụng các hàm tích hợp.


Thay vào đó, có thể cung cấp một hàm tùy chỉnh riêng (hoặc phương thức).


Ở trường hợp này, các hàm Lambda có thể đặc biệt thuận tiện:



>>> list(map(lambda item: 2 * item, [-2, -1, 0, 1, 2]))
[-4, -2, 0, 2, 4]



Câu lệnh trên đã nhân mỗi item của list [-2, -1, 0, 1, 2] với 2 bằng cách sử dụng hàm lambda tùy chỉnh lambda item: 2*item.


Tất nhiên, chúng ta có thể sử dụng sự kỹ thuật 
comprehension để đạt được kết quả tương tự:


>>> [2 * item for item in [-2, -1, 0, 1, 2]]
[-4, -2, 0, 2, 4]


4.2. Filtering



Filtering được thực hiện với class filter (built-in class)


Nó cũng lấy một hàm (hoặc phương thức, hoặc bất kỳ lệnh gọi nào) làm đối số thứ nhất và Iterables làm đối số thứ hai.


Nó gọi hàm trên các item của iterable và trả về một iterable mới với các item mà hàm trả về True hoặc bất cứ thứ gì được đánh giá là True. Ví dụ:



>>> list(filter(lambda item: item >= 0, [-2, -1, 0, 1, 2]))
[0, 1, 2]


Câu lệnh trên trả về list mới với các item > 0 của list [-2, -1, 0, 1, 2], như được định nghĩa với hàm lambdas item: item > 0.


Một lần nữa, chúng ta có thể có kết quả tương tự bằng kỹ thuật comprenhension:



>>> [item for item in [-2, -1, 0, 1, 2] if item >= 0]
[0, 1, 2]


4.3. Reducing



Reducing được thực hiện với hàm reduce từ functools. Một lần nữa, nó cần hai đối số: một hàm và iterables.


Nó gọi hàm trên hai item đầu tiên của iterables, sau đó là gọi hàm trên kết quả này và item thứ 3. v.v.


Cuối cùng, nó trả về một giá trị duy nhất.


Ví dụ: Chúng ta có thể tìm thấy tổng của tất cả các item trong danh sách như thế này:



>>> import functools
>>>
>>> functools.reduce(lambda x, y: x + y, [1, 2, 4, 8, 16])
31



Ở đây:


  1. Lấy 1 + 2 bằng 3
  2. Sau đó lấy 3 + 4 bằng 7
  3. Tiếp tục lấy 7 + 8 bằng 15
  4. Cuối cùng lấy 15 + 16 bằng 31


Ví dụ này chỉ để minh họa về Reduce.


Còn cách tính tổng các item trong thường được sử dụng trong Python là:



>>> sum([1, 2, 4, 8, 16])
31


Bởi vì Python ưu tiên khả năng dễ đọc. Tính tổng các item trong bằng reduce thì quá khó hiểu so với hàm sum.


5. Immutable Data Types: Kiểu dữ liệu bất biến




Một đối tượng bất biến (immutable object) là một đối tượng mà trạng thái của nó không thể được sửa đổi khi nó được tạo ra.


Ngược lại, một đối tượng biến đổi (mutable object) có thể thay đổi, nó cho phép thay đổi trạng thái của nó.


Nói chung, đối tượng bất biến được kỳ vọng ở trong Lập trình Hàm.


Ví dụ: Trong Python, các list có thể thay đổi, trong khi các tuple là bất biến:



>>> a = [1, 2, 4, 8, 16] >>> a[0] = 32 # OK. Bạn có thể sửa đổi lists.
>>> a
[32, 2, 4, 8, 16]
>>> a = (1, 2, 4, 8, 16)
>>> a[0] = 32 # Bạn không thể sửa đổi tuples.
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment


Chúng ta có thể sửa đổi list bằng cách thêm cho chúng các phần tử mới.


Nhưng khi chúng ta cố gắng thực hiện điều này với tuple, chúng không bị thay đổi nhưng các trường hợp mới được tạo:



>>> # Lists (Biến đổi)
>>> a = [1, 2, 4] # a là một list
>>> b = a # a và b tham chiếu đến cùng một list
>>> id(a) == id(b)
True
>>> a += [8, 16] # a được sửa đổi và b cũng thế - Vì chúng tham chiếu đến cùng list
>>> a
[1, 2, 4, 8, 16]
>>> b
[1, 2, 4, 8, 16]
>>> id(a) == id(b)
True
>>>
>>> # Tuples (Bất biến)
>>> a = (1, 2, 4) # a là một tuple
>>> b = a # a và b cùng tham chiếu đến cùng một tuple
>>> id(a) == id(b)
True
>>> a += (8, 16) # một tuple mới được tạo và gán cho a; b không thay đổi
>>> a # a tham chiếu đến một đối tượng mới
(1, 2, 4, 8, 16)
>>> b # b tham chiếu đến đối tượng cũ
(1, 2, 4)
>>> id(a) == id(b)
False


Ưu điểm của Lập trình hàm



Các khái niệm và nguyên tắc cơ bản, đặc biệt là các high-order function, immutable data và việc không có tác dụng khác đã phần nào nói lên những ưu điểm của lập trình hàm.


  • Chúng có thể dễ dàng hiểu hơn, triển khai, kiểm thử và gỡ lỗi.
  • Chúng có thể ngắn hơn và súc tích hơn (ví dụ so sánh hai chương trình để tính giai thừa ở trên).
  • Chúng có thể ít bị lỗi hơn.
  • Chúng dễ dàng làm việc hơn khi thực thi song song.


Qua ví dụ về Lập trình hàm với Python, chúng ta thấy rằng: Lập trình hàm là một mô hình lập trình có giá trị đáng học hỏi.


Ngoài những ưu điểm được liệt kê ở trên, nó có thể cung cấp cho bạn một góc nhìn mới trong việc giải quyết các vấn đề lập trình.


---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học làm Lập trình viên. Hành động ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0914939543
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
 
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #python #java #php
Bình luận Facebook
Mục lục
Đăng ký tư vấn
Nhân viên gọi điện tư vấn miễn phí sau khi đăng ký
Được cập nhật các ưu đãi sớm nhất
Hotline: 0383180086
Tên không được để trống
Số điện thoại không được để trống
Email không được để trống
Hãy đăng ký để nhận những thông tin mới nhất về học bổng mới nhất tại NIIT - ICT Hà Nội
top
Đóng lại Đăng ký học tại NIIT - ICT Hà Nội
6260+ học viên đã theo học tại NIIT - ICT Hà Nội và có việc làm tốt trong ngành lập trình. Nắm lấy cơ hội ngay hôm nay!
Chọn khóa học
  • KHÓA HỌC LẬP TRÌNH FRONT END VỚI REACT.JS
  • KHÓA HỌC LẬP TRÌNH PHP WEB
  • Khóa học PHP Full stack [2023] cho người mới bắt đầu
  • Khóa học BIG DATA với Hadoop và Spark
  • Khóa học Lập trình Android tại Hà Nội
  • [Tuyển sinh 2023] Lập trình viên Quốc tế DigiNxt
  • Khóa học Tiền lương & Phúc lợi (C&B Excel) tại Hà Nội
  • LẬP TRÌNH GAME
    • Khóa học Lập trình Game Unity
  • LẬP TRÌNH WEB FRONT END
    • KHÓA HỌC PYTHON HƯỚNG ĐỐI TƯỢNG
    • KHÓA HỌC ANGULAR & TYPESCRIPT (FRONT END)
  • LẬP TRÌNH WEB BACK END
    • LẬP TRÌNH JAVA WEB VỚI FRAME WORK
    • Lập trình Web với Django
    • Lập trình PHP với Laravel Framework
  • CHƯƠNG TRÌNH ĐÀO TẠO ỨNG DỤNG CÔNG NGHỆ
    • Khóa học Tiền lương & Phúc lợi (C&B Excel) tại TP HCM
  • LẬP TRÌNH WEB FULL STACK
    • Khóa học Java Full stack (IJFD)
  • LẬP TRÌNH MOBILE
    • FRONT-END VỚI REACTJS VÀ REACT NATIVE
    • Lập trình Android Nâng cao
  • ĐÀO TẠO CHO DOANH NGHIỆP
    • KHÓA HỌC BUSINESS ANALYSIC TỪ CƠ BẢN ĐẾN NÂNG CAO 2023
    • Khóa học Magento: Làm chủ CMS TMĐT lớn nhất
    • Khóa học IOT: Xây dựng Sản phẩm IOT với Raspberry Pi
    • Khóa học Automation Testing Chuyên nghiệp
  • KHÓA HỌC DỰ ÁN
    • Học sử dụng bộ Office: Word, Excel, Power Point, Mail chuyên nghiệp
  • KHÓA HỌC KHÁC
    • VBA Excel Toàn Tập (Cơ Bản - Nâng Cao)
    • VBA Excel Nâng cao
    • Khóa học JMeter: Performance Testing
    • Khóa học Tester đạt chuẩn Quốc tế ISTQB Foundation Level
    • Khoá Học Tester đạt chuẩn quốc tế ISTQB Advanced Level
Bạn chưa chọn khóa học cần đăng ký
Tên không được để trống
Số điện thoại không được để trống
Email không được để trống
Đăng ký học thành công!
Cảm ơn bạn đã đăng ký học tại NIIT - ICT HÀ NỘI!