Điều khiển lặp trong python
bảo đảm. “Chào Minh Hoàng. ”. bảo gà. “Chào Bá Lộc. ”. Mẹ Út bảo. “Chào Minh Hoàng”. bảo gà. “Chào Mẹ Út” 🤣 Show Hôm nay anh sẽ cầm gương lên, dũng cảm xông pha ra trận chém con thú hai đầu, một cái đầu màu hồng tên là “Iterator“, một cái đầu màu xanh tên là “Generator“ Để mình kể bạn nghe, đây là câu chuyện có thật, từ chiếc ti vi, kênh Cartoon Network, chương trình hoạt hình “Biệt đội Titan xuất kích”. Hai bạn quái vật này bị nhốt trong một cái hộp thần bí, Raven đã phiêu lưu các bạn không mở được nó ra vì nó rất nguy hiểm, nhưng StarFire đã không có hứng thú tò mò và mở ra. Hai bạn này siêu dễ thương luôn, cùng vui chơi với các bạn nhỏ, nhưng khi hai bạn đó được StarFire Không Nhụy mà hôn cho một cái thì lập tức hai bạn biến hình thành một con quái vật có hai đầu đi khám phá thành phố. Sau đó, StarFire đã nói ra những lời đau lòng đến mức từ con quái vật hai đầu đến với hai bạn càng ngày càng thu bé lại và biến thành hai con nhỏ yêu buồn nôn nôn vì không được yêu thương nữa. Câu chuyện vậy đó, khi mình sáng tác bài này tự sướng mình cũng thấy trùng hợp ghê, hai bạn “Iterator” và “Generator” này cũng dễ thương như vậy, nhưng cũng có thể biến thành quái vật khi mình chủ quan về các bạn . Còn mình mà đã hiểu á, thì sẽ biến lại thành hai bạn tiểu yêu xinh dễ cưng thôi Cho nên là hôm nay, mình cùng quyết tâm chinh phục con quái thú hai đầu này nha. 👻 Ý quên, còn gặp cả sư phụ của bọn nhỏ nữa đấy Bài blog này thuộc series “Khám phá Đại Bản Doanh Trăn” (Hình ảnh được cung cấp bởi artemtation từ Pixabay) Open startTrong nội dung bài “Các công cụ điều khiển luồng dữ liệu”, mình đã biết cách lặp qua các phần tử của các kiểu dữ liệu là tập hợp nhiều phần tử trong đó, như chuỗi, danh sách, dict rồi, dùng cho phần_tử . Và mình cũng đã học cách sử dụng enumerate() để có thể vừa lặp vừa sử dụng chỉ mục số của phần tử, ví dụ
“a” is a list. Nếu a là một bộ thì sao nhỉ? . (Tìm hiểu thêm về các loại dữ liệu ở bài “Cấu trúc dữ liệu trong Python” nhé)
Ôi nó bị sao thế nhỉ, lỗi “TypeError. ‘set’ object is not subscriptable” có nghĩa là kiểu dữ liệu “set” không hỗ trợ truy cập phần tử theo chỉ mục Hiểu nôm na thì nếu a là list, nó có thể truy cập đến phần tử đầu tiên bằng chỉ số là 0 với a[0], còn b là set thì nó không có chỉ số index như vậy nên b[0] sẽ báo lỗi Thế còn kiểu dữ liệu dict thì sao nhỉ?
Úi, vậy là kiểu dữ liệu dict cũng không truy cập được theo chỉ mục index được Do đó, trong Python the same as data type may be contain many element(string, list, set, dict,…) but you are back share doing two group 🥰 Nhóm dữ liệu tuần tự(sequence). chuỗi, danh sách, … cho phép mình truy cập qua các phần tử trong bộ sưu tập bằng chỉ mục, hay gọi là chỉ mục số, các bạn chỉ số này có chỉ mục được đánh dấu từ 0 đến len – 1(chiều dài của nó trừ 🥰 Nhóm dữ liệu tập hợp(bộ sưu tập). set, dict, … không truy cập được theo chỉ mục Rồi sao nữa 😊 Hehe, rồi thì luật sinh ra là để lách luật đó mấy bạn 😅 Không muốn lướt luật tức thời là muốn duyệt có trình tự mấy kiểu tập hợp dữ liệu như set, dict trên, thì mình cần hiểu bản chất và cơ chế của luật này cái đã. Đây chính là sư phụ của hai bạn nhỏ yêu trên, tạm gọi là sư phụ iterable Có thể lặp lạiThực ra gối giờ mình từng gặp nhiều bạn là iterable rồi đó 👉 a và b của những ví dụ trên đều là iterable Một đối tượng là iterable nghĩa là nó có thể lặp lại, hiểu nôm na là if a is iterable thì 👉 could itqua a been, tức là có thể viết *“for x in a” * 👉 call iter(a), will return iter 👉 a có phương thức __iter__ nếu cũng trả về một iterator hoặc đôi khi A có phương thức \getitem\ thuộc nhóm dữ liệu tuần tử có thể truy cập phần tử theo chỉ số chỉ số đã nói ở trên Xem ví dụ iterable is list
Continue by b is a dict nè
Bạn đã thấy sự khác nhau chưa, vậy điểm chung duy nhất của các iterable là có nhiều phần tử và cho phép mình bật qua chúng nó đó. Tuy nhiên, số lượng phần tử trong iterable có thể là hữu hạn hoặc vô hạn, theo ví dụ trên thì chúng có số lượng hữu hạn. Giờ thì cũng đi qua một ví dụ với số lượng phần tử vô hạn nhé Trong ví dụ này, mình sử dụng hàm đếm từ itertools để tạo một bộ đếm là bội số của 3 Khi thực hiện vòng lặp này qua bộ đếm này với vòng lặp cho và trong các phần tử ra thì nó sẽ chạy mãi mãi cho đến khi mình tiếp tục chương trình hoặc mình phải thêm điều kiện dừng cho vòng lặp là khi n > 200 thì thoát khỏi Với số lượng phần tử vô hạn như vậy thì mình không thể chuyển các bạn ấy về kiểu danh sách được. Không kể số lượng phần tử quá lớn sẽ gây hại cho bộ nhớ và hiệu suất của chương trình Hehe, thực ra to test rồi, và nó kill luôn PI và tự thoát ra luôn 😅
Vì những nguyên nhân đó, sư phụ Iterable đã nhận một đệ tử đầu tiên, chính là bạn tiểu yêu màu hồng, bạn mà sau này biến thành quái thú màu hồng trong con quái thú hai đầu đó, bạn ấy tên là Iterator Cùng xem bạn Iterator giúp giải quyết vấn đề trên ra sao nhé Trình lặpThực hiện iterator là một khái niệm trong lĩnh vực khoa học máy tính đấy nhé. This is output body of Iterator from Wikipedia
Bản dịch tạm thời là. Trong lĩnh vực khoa học máy tính, iterator là một đối tượng cho phép các nhà thiết lập có thể duyệt qua một vùng chứa dữ liệu, như danh sách Còn lại trong Python, trình vòng lặp được định nghĩa trong Python wiki là
Bạn đã thấy iterator lần nào chưa nhỉ? Thực ra mình đã thấy bạn ấy khi mình gọi iter(a) ở ví dụ trên đấy, cùng xem mình gọi __next__ thì bạn ấy sẽ trả ra gì nhé
Ồ hay chưa, mình có thể đi qua các phần tử trong a bằng phương thức __next__, thay vì dùng cho nè. Khi đến phần tử cuối cùng rồi thì nó sẽ báo lỗi StopIteration để báo cho mình biết hết đồ để đi tiếp rồi nghen 🤣 Thêm nữa, iterator cũng là iterable đó, cùng xem tớ thích nó với cho nè, và cả gọi iter() cho x thì nó trả về chính nó luôn
Vì vậy, để lặp qua một lần lặp vô hạn, như cái ví dụ bội số của 3 ở trên, mình cần biến nó thành iterator bằng hàm iter(), rồi sau đó có thể sử dụng __next__() hoặc next() để đi qua . Nhưng vì đang nói đến iterable vô hạn nên iterable không bao giờ có ngoại lệ StopIteration luôn đó Cùng xem cách mình đã bật qua “multiplesofthree” sử dụng iterator thay cho nhé Thật vị thú không đúng, mình không sử dụng cho mà vẫn lặp qua các đối tượng của một iterable đấy Và bật mí với các bạn, đây cũng chính là cơ chế lặp được sử dụng nhiều trong Python đấy, cụ thể là cho vòng lặp cho nè, rồi xác định nhiều giá trị trong tuple nè, rồi hiểu danh sách (ví dụ cho bạn nào Trước khi đi tiếp mình xin bùm bùm cho bạn đỡ rối nha Mình đã tìm hiểu về. Có thể lặp lại, Iterator 😊 Iterable was verify by 3 way
😊 Iterator được xác định bằng
Nhìn tóm tắt vào bạn thử cấu hình xem nếu mình muốn tạo một iterable cho riêng mình thì mình cần phải định nghĩa những gì để Python hiểu nó là một iterable nhỉ? To see any, chắc chắn là nó cần có một phương thức là __iter__, và phương thức này cần phải trả về một iterator của bạn Cùng mình cố gắng định nghĩa một lần lặp lại của riêng bạn nhé ________số 8 Ở trên, lớp BlogPost có thể tạo ra các đối tượng có thể lặp lại đó, cùng thử trải nghiệm nha Mình đang thực hiện và giải thích trên video này nè Ui, mãi mê mệt với hai bạn này mà mình sắp đến thời gian rồi, nhanh nhanh đi tiếp chú tiểu yêu tiếp theo cần phải chinh phục, đó là chú màu xanh máy phát điện Máy phát điệnThis is output body of Generator from Wikipedia
Bản dịch tạm thời là. Trong lĩnh vực khoa học máy tính, máy phát điện là một bộ quy trình mà những người có thể sử dụng để kiểm tra hành động của một vòng lặp. And all generator also iterators Còn lại trong Python, trình tạo được định nghĩa trong Python wiki là trình tạo hàm hay gọi là trình tạo hàm, cho phép bạn tạo ra một hàm hoạt động tương tự như một trình lặp, tức là nó cũng có thể lặp lại và có thể sử dụng với vòng lặp cho Use generator in any fieldsMình là một bạn nhỏ hay thắc mắc, mình cũng rất tò mò lý do tại sao lại cần có hàm tạo nhỉ? Bạn đoán thử cùng mình xem sao? Mình nghĩ là nếu tạo iterator khoai như ở trên, thì buồn thật đấy, khi nào cũng viết phương thức __iter__ rồi nó phải trả về iterator, rồi muốn trả về iterator thì lại phải đi định nghĩa phương thức __next__ và viết cái logic khác . Thật tình mà nói thì cũng hơi khó ghét đó nha 🥲 Chắc là mấy chú Python thấy thế thì nghĩ ra một cách, hay là mình cho đám nhỏ viết một hàm thôi, và hàm đó hoạt động như một iterator, còn những thứ lằng nhằng kia để các chú lo, phải không? Hihi, đoán sao mà nó trúng rồi nha, chính xác là generator giúp mình tạo iterator một cách dễ dàng hơn nhiều. Và thêm nữa, trình tạo sẽ thường được sử dụng cho các trường hợp cần xem xét về hiệu suất của chương trình, ví dụ như khi mình làm việc với số lượng siêu lớn, hay làm việc với các tệp có dung lượng lớn cần xử lý Vì sao? Nếu bạn gặp những trường hợp này, thì generator chính là chân ái của đời bạn đó, nhớ nhé 😘 Ví dụ cho cáiđề bài. tạo một danh sách các số từ 0 đến n, sau đó tính tổng của chúng. Please try to try with n = 1000000000 nhé Nào, giờ mình sẽ đi cùng mọi người giải bài toán bằng ba cách nhé Cách 1. sử dụng một danh sách để lưu các số
Và mình đang chạy thử xem nó tốn bao nhiêu thời gian 0Rồi, đoạn mã này khá đơn giản phải không, logic rất dễ hiểu, nhưng nó đang tạo một danh sách với tất cả các phần tử từ 0 đến n, rồi cộng lại. Rõ ràng là phương án này nhìn thì đơn giản, nhưng rất khó tiếp nhận trong trường hợp n là số siêu lớn, vì làm sao mà mình lưu hết cả 1000000000… phần tử trong bộ nhớ được Với n = 1000000000000000, chương trình sẽ đứng sau một nỗ lực hồi sinh hiu hiu, thương ghê 1cách 2. sử dụng iteratorĐầu tiên, mình sẽ tiến gần cách số 2 với bạn iterator trước nha, vì bạn này cũng giúp mình không lưu cả dãy như ở trên, và vẫn có thể xử lý vấn đề này ha Ôkê, tại bạn ni hơi cực nên mình lại nhắc tí là mình tính làm gì nha. Đầu tiên là mình cần tạo một lớp có phương thức __iter__ sau đó phương thức này trả ra iterator, ở đây là mình muốn gom hết vào một chỗ luôn, vì mình hiểu là iterator cũng là iterable nên mình sẽ trở lại chính mình ở đây. Sau đó mình sẽ tạo tiếp một phương thức __next__ để chính nó là iterator Cùng xem mã nha 2Còn đây là thời gian chạy của mã đoạn với iterator nhé 3Và tất nhiên là đoạn mã trên có thể hoạt động ổn định hơn rồi Tuy nhiên có vài vấn đề mà mình từng đoán trước đây như là – Nhiều mã quá, bao gồm lớp rồi phương thức,… – Và logic khá rắc rối, trừ khi bạn hiểu sâu về iterator, iterable còn không thì nhìn vào đã hoa mắt rồi Chưa hết, nếu dùng đoạn mã này quay lại thì nhiều nơi sẽ làm cho đoạn mã dài hơn đấy. Vì thế, Python đã hỗ trợ trình tạo của mình, bạn này được giới thiệu từ PEP255 Cách 3. sử dụng người anh hùng máy phát điện, chân ái khi làm việc với số lượng lớn và dữ liệu lớn Cùng viết lại mã trên máy phát điện nhé. Bạn sẽ ngạc nhiên vì độ thanh lịch của nó đấy 4And your time this time run is 5*Lưu ý nhỏ là thời gian chỉ mang tính chất so sánh khách quan thôi nha, vì nó còn phụ thuộc vào máy của tớ nữa ý. * Cách tạo máy phát điệnCách 1. Sử dụng trình tạo hàmĐây chính là cách mà ví dụ ở trên dùng đấy Để tạo hàm tạo thì mình tạo hàm như bình thường và thay vì dùng return để trả về giá trị thì mình dùng yield để trả về giá trị cách 2. Sử dụng trình tạo biểu thứcNgoài ra, còn có thể sử dụng trình tạo biểu thức để tạo nữa, biểu thức này tương tự như cách hiểu danh sách đó, mà thay dấu [] bằng dấu () thôi 6Vì hôm nay mình đã cùng gặp qua sư phụ iterable và chiến đấu với hai bạn nhỏ yêu iterator và generator rồi. Bạn quái thú hai đầu này dù có sự trợ giúp sức lực của sư phụ iterable nữa nhưng vẫn đầu hàng trước sự cố gắng của bọn mình và cả ba đều biến thành các bạn yêu nhỏ xinh Điều khiển rồi đó. 🥳 |