Chương 5 [Giới thiệu] của cuốn sách thảo luận về cách làm việc với các tập hợp toán học trong Python. Trong khi viết chương này, tôi đã lựa chọn sử dụng cấu trúc dữ liệu có sẵn của Python 3 hay sử dụng [0. 7. 6 +] Lớp FiniteSet. Tôi quyết định tiếp tục với cái sau. Sự lựa chọn của tôi được giải thích ngắn gọn ở cuối bài viết này, nhưng hy vọng rằng nó sẽ rõ ràng trước đó
Tiếp theo, tôi mô tả cách bạn có thể sử dụng cấu trúc dữ liệu tập hợp tích hợp sẵn của Python 3 để tạo tập hợp và thực hiện các thao tác tập hợp, chẳng hạn như tìm phép hợp, giao hoặc tích cartesian của các tập hợp. Để so sánh, tôi cũng chỉ ra cách bạn có thể làm tương tự bằng cách sử dụng lớp FiniteSet của SymPy
Tạo một tập hợp
Ta có thể tạo set gồm các phần tử {1, 2, 3} trong Python 3 như sau
>>> s1 = {1, 2, 3} >>> s1 {1, 2, 3}
Để tạo một tập hợp khi các phần tử đã có trong danh sách [ví dụ], chúng ta sẽ sử dụng cú pháp sau
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}
Các hoạt động so sánh sử dụng lớp FiniteSet của SymPy là
>>> from sympy import FiniteSet >>> s1 = FiniteSet[1, 2, 3] >>> s1 {1, 2, 3} >>> items = [1, 2, 3] >>> s2 = FiniteSet[*items] >>> s2 {1, 2, 3}
Để tạo một tập hợp trống, trong Python 3, bạn sẽ sử dụng tạo một đối tượng tập hợp trống
>>> e = set[] >>> e set[]
Trong SymPy, một tập rỗng được đại diện bởi một đối tượng EmptySet. Do đó, bạn có thể tạo một tập hợp trống bằng cách tạo trực tiếp một đối tượng EmptySet hoặc bằng cách tạo một đối tượng FiniteSet mà không chỉ định bất kỳ thành viên tập hợp nào, như vậy
>>> from sympy import EmptySet >>> e = EmptySet[] >>> e EmptySet[] >>> e = FiniteSet[] >>> e EmptySet[]
Cardinality và thành viên
Hàm len[] trả về số thành viên tập hợp cho các tập hợp được tạo bằng một trong hai cách tiếp cận trên
Tương tự, để kiểm tra xem một phần tử x có trong tập hợp s được tạo bằng cách sử dụng bất kỳ phương pháp nào ở trên hay không, chúng ta có thể sử dụng câu lệnh, x in s
Liên minh và giao lộ
Phương thức union[] có thể được sử dụng trong cả hai trường hợp để tìm hợp của hai hoặc nhiều tập hợp
>>> s1 = set[[1, 2, 3]] >>> s2 = set[[2, 3, 4]] >>> s3 = set[[2, 3, 4, 5]] >>> s1.union[s2].union[s3] {1, 2, 3, 4, 5}
Sự tương đồng trong trường hợp của SymPy
>>> from sympy import FiniteSet >>> s1 = FiniteSet[1, 2, 3] >>> s2 = FiniteSet[2, 3, 4] >>> s3 = FiniteSet[2, 3, 4, 5] >>> s1.union[s2].union[s3] {1, 2, 3, 4, 5}
Phương thức giao nhau [] có thể được sử dụng để tìm giao điểm của hai hoặc nhiều tập hợp được tạo bằng một trong hai cách tiếp cận trên. Tiếp tục với ba bộ trên
>>> s1 = set[[1, 2, 3]] >>> s2 = set[[2, 3, 4]] >>> s3 = set[[2, 3, 4, 5]] >>> s1.intersection[s2].intersection[s3] {2, 3}
Tương tự, trong SymPy
________số 8
tích Descartes
Để tìm tích cartesian của các tập hợp được tạo thông qua cấu trúc dữ liệu tập hợp tích hợp sẵn, chúng ta phải sử dụng hàm product[] trong mô-đun
>>> s1 = {1, 2, 3} >>> s2 = {4, 5, 6} >>> import itertools >>> itertools.product[s1, s2]
Tuy nhiên, xét rằng tích cartesian của hai tập hợp phải là một tập hợp khác, hàm product[] sau đó không thực sự trả về chính tích cartesian, mà trả về [một trình vòng lặp cho] các phần tử trong đó. Do đó, nếu chúng ta cố gắng áp dụng trực tiếp kết quả trả về của hàm cho một phương thức hoặc hàm dự kiến sẽ áp dụng được cho một tập hợp, thì nó sẽ thất bại. Ví dụ, itertools. sản phẩm[s1, s2]. union[s3] sẽ dẫn đến lỗi, nhưng set[itertools. sản phẩm[s1, s2]]. union[s3] sẽ hoạt động.
Sử dụng FiniteSet của SymPy, bạn có thể sử dụng toán tử * [phép nhân hoặc tích] để tìm tích cartesian và kết quả là một tập hợp. Do đó, nó gần với tích Descartes hơn về mặt toán học. Một ví dụ sau
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}0
Tích Descartes của một tập hợp với chính nó
Để tìm tích cartesian của một tập hợp với chính nó, i. e. s1*s1 chẳng hạn, chúng tôi chuyển vào một đối số từ khóa, lặp lại trong khi gọi itertools. hàm sản phẩm []. Giá trị của lặp lại là sức mạnh mà chúng tôi muốn nâng tập hợp lên. Vì vậy, itertools. product[s1, repeat=2] sẽ tính tích cartesian, s1*s1
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}1
Trong SymPy, toán tử ** có thể được sử dụng để tìm tích cartesian của một tập hợp với chính nó
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}2
Kiểm tra tập hợp con/siêu tập hợp/tập hợp con thích hợp
Các phương thức issubset[] và issuperset[] có sẵn cho các tập hợp được tạo thông qua một trong hai cách tiếp cận để kiểm tra xem một tập hợp có phải là tập hợp con và siêu tập hợp của một tập hợp khác hay không. Như vậy, s1. issubset[s2] sẽ kiểm tra xem s1 có phải là tập con của s2 không
Kiểm tra tập hợp con và superset thích hợp
Để kiểm tra xem một tập hợp, s1 có phải là tập hợp con thích hợp của một tập hợp khác, s2 hay không khi sử dụng tập hợp sẵn, chúng ta có thể làm như sau
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}3
Chúng ta có thể làm một cái gì đó tương tự cho superset thích hợp
Trong SymPy, chúng ta có các phương thức is_proper_subset[] và is_proper_superset[] có thể được sử dụng để kiểm tra xem một tập hợp có phải là tập hợp con hoặc tập hợp con thích hợp của tập hợp khác hay không, tương ứng. Vì vậy, ở trên sẽ được viết là s1. is_proper_subset[s2]
Tính toán bộ nguồn
Đối với các tập hợp được tạo thông qua cấu trúc dữ liệu tập hợp tích hợp, không có phương pháp trực tiếp nào khả dụng để tạo tập hợp năng lượng. Tuy nhiên, bạn có thể sử dụng công thức bộ nguồn được mô tả trong
Mặt khác, trong SymPy, có sẵn một phương thức powerset[] trả về bộ nguồn
>>> items = [1, 2, 3] >>> s2 = set[items] >>> s2 {1, 2, 3}4
Bạn có thể thấy rằng phương thức powerset[] trả về tập hợp sức mạnh chứ không phải các phần tử trong đó
Lựa chọn FiniteSet của SymPy trên bộ
Từ so sánh trên, chúng ta có thể thấy FiniteSet của SymPy cung cấp cho chúng ta những tính năng hay như có thể sử dụng toán tử * để tìm tích cartesian, toán tử ** để tính tích cartesian với chính nó và phương thức powerset[] để tính lũy thừa . Chúng không xuất hiện khi sử dụng cấu trúc dữ liệu tập hợp tích hợp. Đây chắc chắn là một yếu tố thúc đẩy lớn trong sự lựa chọn của tôi, vì SymPy cũng đã được sử dụng trong các chương khác của cuốn sách
Tuy nhiên, lý do chính cho sự lựa chọn của tôi là tôi muốn chỉ ra cách chúng ta có thể tạo các tập hợp không cho phép thêm hoặc xóa sau khi đã tạo - như các tập hợp toán học. Nhu cầu này đã được đáp ứng bởi FiniteSet của SymPy vì nó sử dụng cấu trúc dữ liệu freezeset của Python chứ không phải cấu trúc dữ liệu đã đặt
Giải pháp thay thế cho điều đó là sử dụng freezeset trực tiếp, nhưng tôi không thích ý tưởng về nó và tôi cũng đã bỏ lỡ các tính năng hay mà FiniteSet sẽ cung cấp [cuối cùng]. Tôi nên lưu ý ở đây rằng một khi tôi đã quyết định sử dụng FiniteSet, tôi đã đóng góp các bản vá cho SymPy để làm cho các phương thức của FiniteSet tương thích hơn với bộ tích hợp sẵn của Python và cũng triển khai các tính năng nhỏ mà tôi đã thảo luận ở trên