Bạn đã bao giờ tình cờ gặp một tính năng của Python và nghĩ, “Giá mà mình biết điều này sớm hơn!”? Bạn không cô đơn! Trong bài viết này, VietnamWorks inTECH sẽ chia sẻ 20 tính năng của Python có thể giúp hành trình gõ code của bạn suôn sẻ hơn. 

1. List Comprehensions

List Comprehensions là một cách ngắn gọn để tạo một danh sách mới bằng cách áp dụng một biến đổi cho mỗi phần tử của danh sách hiện có, thỏa mãn một điều kiện nhất định. 

Bạn nên sử dụng List Comprehensions khi bạn muốn rút gọn các vòng lặp và điều kiện trong quá trình tạo danh sách mới. Điều này giúp mã nguồn trở nên ngắn gọn và dễ đọc hơn, đặc biệt là khi bạn cần xử lý các danh sách lớn.

Ví dụ: Nếu cần tìm bình phương của tất cả các số chẵn trong một dãy, chúng ta có thể sử dụng:

squares = [x**2 for x in range(10) if x % 2 == 0]

Lưu ý: Tránh sử dụng tính năng này lồng nhau vì chúng có thể làm giảm tính dễ đọc của chương trình. Hơn nữa, nếu tính logic trở nên phức tạp thì tốt hơn nên sử dụng vòng lặp for.

2. Hàm Lambda

Hàm Lambda trong Python là một hàm vô danh hay hàm ẩn danh (Anonymous function), một hàm mà không có tên. Đây là một hàm nhỏ và bị hạn chế, không có nhiều hơn một dòng. Cũng giống như một hàm bình thường, một hàm Lambda có thể có nhiều đối số với một biểu thức.

Hàm Lambda thường được sử dụng khi cần một hàm vô danh trong một thời gian ngắn. Trong Python, mọi người sử dụng nó như một đối số cho bậc hàm cao hơn (một hàm nhận các hàm khác làm đối số). Hàm Lambda được sử dụng cùng với các hàm tích hợp sẵn như filter(), map() hay reduce().

Hàm Lambda cũng có thể được sử dụng để tạo ra các hàm tùy chỉnh, có thể sử dụng lại và gọi chúng bằng tên thân thiện.

Ví dụ: Sắp xếp danh sách các chuỗi dựa trên độ dài của chúng:

words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))

Lưu ý: Hàm Lambda có thể làm giảm khả năng đọc hiểu khi sử dụng quá mức hoặc khi tinh logic trở nên phức tạp. Trong những trường hợp như vậy, tốt hơn hết bạn nên xác định một hàm thích hợp.

3. Hàm Map, Filter và Reduce

Hàm Map, Filter và Reduce là ba hàm đặc thù của lập trình hàm. Đặc điểm chung của chúng là cho phép áp dụng một hàm xử lý trên một danh sách dữ liệu:

  • Hàm Map thường được sử dụng khi bạn muốn chuyển đổi các phần tử trong một mảng. 

  • Hàm Filter thường được sử dụng khi bạn muốn chọn một tập hợp con gồm nhiều phần tử từ một mảng. 

  • Hàm Reduce thường được sử dụng khi bạn muốn lấy một giá trị từ nhiều phần tử trong một mảng.

Bạn có thể sử dụng các hàm này để rút gọn các vòng lặp và điều kiện trong Python, giúp mã nguồn trở nên ngắn gọn và dễ đọc hơn, đặc biệt là khi bạn cần xử lý các danh sách lớn.

Ví dụ: Sử dụng hàm map để chuyển chuỗi thành chữ hoa:

names = ["alice", "bob", "charlie"]
upper_names = list(map(str.upper, names))

Lưu ý: hàm map và filter trả về các trình vòng lặp trong Python phiên bản 3.x. Để có được một danh sách, bạn cần chuyển đổi chúng thành list.

4. Decorators

Tương tự với Lambda, hàm Decorator trong Python là một hàm vô danh hoặc hàm ẩn danh, một hàm được định nghĩa mà không có tên. Decorator cho phép các lập trình viên có thể thêm một chức năng mới cho một hàm mà không cần thay đổi mã nguồn của hàm đó. Thay vào đó, bạn có thể tạo một decorator mới để thực hiện một tác vụ cụ thể, ví dụ như kiểm tra tham số đầu vào, đo thời gian thực thi, hoặc xác thực người dùng.

Ví dụ: Một Decorators đơn giản để đo thời gian thực hiện của một hàm:

import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} executed in {end_time - start_time} seconds")
return result
return wrapper
@timer_decorator
def sample_function():
time.sleep(2)

Lưu ý: Tránh lạm dụng hàm Decorator quá nhiều vì nó sẽ khiến code của bạn khó đọc

5. Generators

Generators trong Python là một cú pháp đơn giản hơn giúp bạn tạo ra iterable và iterator thay cho mô hình iterator cơ bản. Bạn có thể sử dụng generator với class, function và expression.

Generator trong Python là một trong những hàm trả về một đối tượng (iterator) mà ở đó chúng ta có thể lặp lại (một giá trị ở một thời điểm). Generator chỉ có thể tạo ra một phần tử theo dạng thời điểm nên có thể biểu thị các luồng dữ liệu vô hạn nhất mà không cần phải lưu trữ trong toàn bộ bộ nhớ.

Ví dụ:Một trình tạo để tạo chuỗi Fibonacci:

def fibonacci(n):
a, b =
0, 1
for _ in range(n):
yield a
a, b =
b, a + b

Lưu ý: Generators là trình lặp; một khi đã dùng thì chúng không thể được tái sử dụng.

6. f-Strings

f-Strings là một cú pháp định dạng chuỗi được cải thiện trong Python 3. Nó cung cấp một phương pháp mới và cải tiến để định dạng chuỗi trong Python. f-Strings không chỉ dễ đọc hơn, ngắn gọn hơn và ít bị lỗi hơn so với các cách định dạng khác mà tốc độ xử lý còn nhanh hơn gấp nhiều lần.

Ví dụ:

name = "Alice"
greeting = f"Hello, {name}!"

7. *args và **kwargs

*args và **kwargs là cú pháp trong Python được sử dụng để truyền đối số cho hàm mà không cần xác định trước số lượng đối số.

  • *args là một tuple chứa các đối số không tên

  • **kwargs là một từ điển chứa các đối số có tên

Ví dụ: 

def multiply(*args):
result = 1
for num in args:
result *= num
return result

8. Type Hinting

Type Hinting trong Python là một cú pháp được sử dụng để chỉ định kiểu dữ liệu của một biến khi khai báo. Type Hinting giúp cho việc đọc hiểu code dễ dàng hơn, giảm thiểu lỗi và tăng tính rõ ràng của code.

Ví dụ:

def greet(name: str) -> str:
return f"Hello, {name}!"

Lưu ý: Python vẫn là ngôn ngữ Dynamically Typed. Type Hinting chỉ là gợi ý và sẽ không thực thi việc kiểm tra type trừ khi bạn sử dụng các công cụ như `mypy`.

9. Context Managers

Context Managers trong Python là một cú pháp được sử dụng để quản lý tài nguyên một cách hiệu quả và tự động giải phóng tài nguyên sau khi sử dụng. Context Managers được sử dụng rộng rãi thông qua câu lệnh with.

Ví dụ: Mở và đọc file

with open('file.txt', 'r') as f:
content
= f.read()

Lưu ý: Việc quên sử dụng câu lệnh `with` có thể dẫn đến tài nguyên không được giải phóng, có khả năng gây rò rỉ bộ nhớ hoặc các vấn đề khác.

10. Walrus Operator

Walrus Operator là một toán tử mới trong Python 3.8, được gọi là toán tử hải mã vì cú pháp của nó giống với khuôn mặt của một con hải mã. Toán tử này cho phép bạn gán giá trị cho một biến trong một biểu thức điều kiện.

Ví dụ: Đọc các dòng từ một tập tin cho đến khi tìm thấy một dòng trống:

with open('file.txt', 'r') as f:
while (line := f.readline().strip()):
print(line)

11. Namedtuples

Namedtuples trong Python là một cú pháp được sử dụng để tạo ra một đối tượng giống như tuple. Các đối tượng Namedtuple có thể được tham chiếu bằng cách sử dụng việc giải tham chiếu biến giống như đối tượng hoặc cú pháp tuple tiêu chuẩn. Các đối tượng Namedtuple có thể được sử dụng tương tự như các kiểu các kiểu ghi chú khác, ngoại trừ việc chúng không thay đổi.

Ví dụ: 

from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
alice = Person(name="Alice", age=30)

Lưu ý: vì chúng không thể thay đổi nên hãy cân nhắc khi tạo cú pháp này. Đối với các cấu trúc có thể thay đổi, hãy cân nhắc sử dụng các lớp dữ liệu (Python 3.7+).

12. Enumeration (enumerate)

Hàm enumerate() trong Python là một hàm được sử dụng để liệt kê các phần tử của một đối tượng iterable (như danh sách, tuple, chuỗi, v.v.) cùng với chỉ số của chúng. Hàm này trả về một đối tượng liệt kê, mà mỗi phần tử của nó là một tuple chứa một cặp giá trị: chỉ số và phần tử tương ứng trong đối tượng iterable.

Hàm sẽ giúp cho các vòng lặp trong Python trở nên rõ ràng và dễ đọc hơn. Ngoài ra, còn tránh việc phải tạo chỉ số một cách thủ công.

Ví dụ: 

names = ["Alice", "Bob", "Charlie"]
for index, name in enumerate(names):
print(f"{index}: {name}")

13. Zipping và Unzipping Lists

Zipping và Unzipping là hai khái niệm được sử dụng trong lập trình để nén và giải nén các danh sách (list) trong Python.

Zipping là quá trình kết hợp các phần tử từ hai hoặc nhiều danh sách khác nhau thành một danh sách mới. Kết quả của quá trình này là một danh sách mới, trong đó mỗi phần tử là một tuple chứa các phần tử tương ứng từ các danh sách ban đầu. 

Unzipping là quá trình chuyển đổi một danh sách các tuple thành nhiều danh sách riêng biệt.

Ví dụ: 

names = ["Alice", "Bob"]
scores = [85, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}")

14. Dictionaries — get() vs setdefault()

Trong Python, get() và setdefault() là hai phương thức được sử dụng để truy cập và thêm các phần tử vào từ điển (dictionary).

Phương thức get() được sử dụng để truy cập giá trị của một key trong từ điển. Nếu khóa không tồn tại trong từ điển, phương thức này sẽ trả về giá trị mặc định (nếu được chỉ định) hoặc None.

Phương thức setdefault() được sử dụng để thêm một khóa mới vào từ điển nếu khóa đó chưa tồn tại. Nếu khóa đã tồn tại, phương thức này sẽ trả về giá trị hiện có của khóa đó.

Ví dụ:

data = {"name": "Alice"}
age = data.get("age", 30)
data.setdefault("country", "USA")

15. The __main__ Guard

__main__ là một thuộc tính đặc biệt trong Python, được sử dụng để xác định xem một module có được thực thi như một chương trình độc lập hay như một module được nhập vào từ một chương trình khác. Khi một module được thực thi như một chương trình độc lập, giá trị của thuộc tính __name__ sẽ được đặt thành __main__. 

Ví dụ, nếu bạn muốn thực thi một module như một chương trình độc lập, bạn có thể đặt mã của mình trong một điều kiện if __name__ == "__main__":. Điều này đảm bảo rằng mã chỉ được thực thi khi module được sử dụng như một chương trình độc lập, và không được thực thi khi module được nhập vào từ một chương trình khác.

16. Virtual Environments

Virtual Environment trong Python là một môi trường ảo, giúp bạn tạo ra một môi trường độc lập, riêng biệt để phát triển và chạy các ứng dụng Python mà không ảnh hưởng đến môi trường toàn cục của hệ thống.

Một số công dụng của Virtual Environment:

  • Cho phép bạn cài đặt các phiên bản khác nhau của các packages Python mà không ảnh hưởng đến các packages đã được cài đặt sẵn trên hệ thống.

  • Kiểm soát các dependencies của các ứng dụng Python.

  • Kiểm soát các phiên bản Python khác nhau trên cùng một hệ thống.

17. Toán tử dấu hoa thị (*)

Dấu hoa thị (*) là một biểu tượng hình ngôi sao được sử dụng trong Python để thực hiện nhiều chức năng khác nhau.

Một trong những chức năng phổ biến nhất của dấu hoa thị là sử dụng nó để thực hiện việc unpacking các đối số trong một hàm. Khi sử dụng dấu hoa thị với một danh sách hoặc tuple, các phần tử của danh sách hoặc tuple sẽ được truyền vào hàm như các đối số riêng lẻ.

Ngoài ra, dấu hoa thị cũng được sử dụng để tạo ra các biến động trong Python.

Ví dụ:

def func(a, b, c):
return a + b + c
values = [1, 2, 3]
print(func(*values))

Lưu ý: không nên quá lạm dụng chức năng này vì nó sẽ khiến code của bạn khó đọc, đặc biệt là khi giải nén nhiều package liên tiếp.

18. Mệnh đề else trong vòng lặp

Trong Python, mệnh đề else có thể được sử dụng với vòng lặp for và while. Mệnh đề else sẽ được thực thi khi vòng lặp kết thúc một cách bình thường, tức là không bị dừng bởi lệnh break.

 Ví dụ:

for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
break
else:
print(n, "is a prime number.")

19. Deepcopy vs. Shallow Copy

Shallow copy là một bản sao của đối tượng gốc, trong đó các tham chiếu đến các đối tượng con được giữ nguyên. Điều này có nghĩa là khi bạn thay đổi một đối tượng con trong bản sao, đối tượng gốc cũng sẽ bị thay đổi. Để tạo một bản sao shallow copy, bạn có thể sử dụng phương thức copy() hoặc toán tử [:].

Deep copy là một bản sao của đối tượng gốc, trong đó các đối tượng con được sao chép hoàn toàn. Điều này có nghĩa là khi bạn thay đổi một đối tượng con trong bản sao, đối tượng gốc sẽ không bị thay đổi. Để tạo một bản sao deep copy, bạn có thể sử dụng phương thức deepcopy() trong module copy.

Sự khác biệt giữa deep copy và shallow copy là rất quan trọng trong việc xử lý các đối tượng phức tạp trong Python. Nếu bạn muốn tạo một bản sao của một đối tượng và không muốn thay đổi đối tượng gốc, bạn nên sử dụng deep copy. Nếu bạn chỉ muốn tạo một bản sao đơn giản của đối tượng, bạn có thể sử dụng shallow copy.

Ví dụ:

import copy
original = [[1, 2, 3], [4, 5, 6]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)

20. Công dụng của dấu gạch dưới (_) của Python

Trong Python, dấu gạch dưới (_) được sử dụng với nhiều mục đích khác nhau. Dưới đây là một số trong số những mục đích phổ biến nhất:

  • Chỉ ra rằng một biến, phương thức hoặc thuộc tính được dùng cho mục đích nội bộ trong một module, class hoặc hàm và không phải là một phần của API.

  • Lưu giá trị của biểu thức cuối cùng được thực thi trong phiên tương tác với Python.

  • Bỏ qua các giá trị cụ thể trong một danh sách hoặc tuple.

  • Sử dụng dấu gạch dưới đơn (_) như một biến tạm thời để chỉ ra rằng một phần kết quả của một hàm đang được bỏ qua.

Ví dụ:

for _ in range(5):
print("Hello, World!")

Lời kết

Như vậy, VietnamWorks inTECH đã vừa điểm qua 20 tính năng và cú pháp xịn xò trong Python. Hy vọng bạn đã bỏ túi được cho mình những tính năng hữu ích và đừng quên chia sẻ cho bạn bè cùng biết nhé!

VietnamWorks inTECH