Chuyển đến nội dung chính
Mô-đun 6 · Bài học 3 trong tổng số 423/36 trong khóa học~10 min
Bài học theo mô-đun (3/4)

biểu thức máy phát điện

Biểu thức trình tạo giống như một cách hiểu danh sách, nhưng với dấu ngoặc đơn thay vì dấu ngoặc vuông. Sự khác biệt rất ấn tượng: nó không tạo danh sách trong bộ nhớ, nó tạo ra các phần tử theo yêu cầu, từng cái một.

Python
gen = (n * n for n in range(1_000_000))
# istantaneo, memoria costante: nessun calcolo ancora fatto

list_comp = [n * n for n in range(1_000_000)]
# alloca 1M di int in memoria

Lười biếng (đánh giá lười biếng)

Trình tạo không làm gì cho đến khi ai đó yêu cầu giá trị tiếp theo:

Python
gen = (n * n for n in range(5))
next(gen)    # 0    (calcolato adesso)
next(gen)    # 1
next(gen)    # 4
# ... e così via, fino a StopIteration

Nó cạn kiệt: sau khi tiêu thụ tất cả các phần tử, nó trống mãi mãi. Để sử dụng lại nó, bạn phải tạo lại nó.

Khi nào nên sử dụng nó

Khi bạn chuyển kết quả cho một hàm tiêu thụ chúng theo trình tự:

Python
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costante

sum, any, all, max, min, "".join(...) đều chấp nhận máy phát điện. Nếu hàm ngoài chỉ yêu cầu dấu ngoặc đơn gọi, bạn có thể bỏ qua phần riêng của máy phát điện:

Python
sum((n * n for n in range(10)))    # OK
sum(n * n for n in range(10))      # IDENTICO, più leggibile

any và all: đoản mạch

any(...) và all(...) ngừng lặp lại ngay khi họ có câu trả lời. Với một trình tạo, các phần tử sau thậm chí không được tính toán.

Python
nums = [1, 2, 3, 4, 5]
any(n > 3 for n in nums)    # True (si ferma a 4)
all(n > 0 for n in nums)    # True
all(n > 2 for n in nums)    # False (si ferma a 1)

Hoa văn: đường ống lười biếng

Python
righe = (linea.strip() for linea in testo.splitlines())
non_vuote = (r for r in righe if r)
prime_dieci = []
for r in non_vuote:
    prime_dieci.append(r)
    if len(prime_dieci) == 10:
        break

Không có danh sách trung gian, ngay cả trên đầu vào lớn.

Tiêu thụ máy phát điện với tổng, bất kỳ, tất cả

Biểu thức trình tạo hoàn hảo để truyền trực tiếp đến các hàm sử dụng các lần lặp, như sum(), any() hoặc all(). Trong trường hợp này, bạn có thể bỏ qua dấu ngoặc đơn bên ngoài của biểu thức trình tạo, chỉ cần viết:

Python
squares_sum = sum(x**2 for x in range(10))

Điều này giữ cho mã của bạn sạch sẽ và tiết kiệm bộ nhớ cao.

Hãy thử nó

tập thể dục#python.m6.l3.e1
Nỗ lực: 0Đang tải…

Tính tổng bình phương của các số từ 1 đến 100 (bao gồm) bằng cách sử dụng biểu thức tạo bên trong sum(). Gán nó cho `tot`. Đánh giá `tot`.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

phạm vi (1, 101) bao gồm 100.

Giải pháp khả dụng sau 3 lần thử

Xem lại bài tập

tập thể dục#python.m6.l3.e2
Nỗ lực: 0Đang tải…

Cho `words = ['ciao', 'mondo', 'PYTHON', 'java']`, hãy sử dụng bất kỳ() nào với biểu thức trình tạo để kiểm tra xem ÍT NHẤT một từ có phải là chữ hoa hay không (.isupper()). Gán kết quả cho `has_uppercase`. Đánh giá `has_uppercase`.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

bất kỳ(p.isupper() cho p trong từ)

Giải pháp khả dụng sau 3 lần thử

Thử thách bổ sung

tập thể dục#python.m6.l3.e3
Nỗ lực: 0Đang tải…

Use a generator expression passed directly to the `sum()` function to calculate the sum of the squares of all integers from 1 to 100 inclusive. Store the result in `total_sum` and evaluate it.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Viết Total_sum = sum(x**2 cho x trong phạm vi (1, 101)). Dấu ngoặc kép là không cần thiết.

Giải pháp khả dụng sau 3 lần thử