10 điều lập trình viên Python nên biết - Phần 2



  • 10 điều lập trình viên Python nên biết - Phần 1

    4. List Comprehension (Cách viết code ngắn gọn để tạo một List phức tạp)

    Theo tôi, list comprehension là thứ nói lên được vẻ đẹp và sự đơn giản của Python. Nhớ những dòng code tôi đã viết trước đó chứ? Đoạn mà tạo một list chứa các số chẵn từ [2, 16] trong phần về Shell Python. Tôi có thể viết lại nó chỉ trong một dòng

    >>> list1 = [i for i in range(2,16,2)]  
    

    Để hiểu được cú pháp, hãy tham khảo ở đây.

    Thông thường, nếu có nhiều vòng lặp với nhiều điều kiện, thì chia code thành từng phần sẽ dễ nhìn hơn:

    list2 = [(x, x**2, y) for x in range(5):
                                for y in range(3):
                                    if x != 2]
    

    Tuy nhiên có thể viết gọn hơn:

    list2 = [(x, x**2, y) for x in range(5) for y in range(3) if x != 2]
    

    Kết quả là:

    list2 = [(0, 0, 0), (0, 0, 1), (0, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (3, 9, 0), (3, 9, 1), (3, 9, 2), (4, 16, 0), (4, 16, 1), (4, 16, 2)]
    

    Hoàn toàn có thể tạo những list lồng nhau thông qua list comprehension. Điều này rất hữu ích nếu như ai đó muốn tạo nên một bảng hoặc một ma trận. Ví dụ:

    >>> list3 = [[0 for i in range(3)] for i in range(3)]  
    >>> list3  
    [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    

    5. Slicing

    Slicing là quy trình lấy một tập con của một dữ liệu. Thường áp dụng với chuỗi và list. Câu chuyện của tôi là khi tôi lần đầu học về slicing, tôi đã dùng một vòng lặp qua một list và áp một hàm cho tất cả các phần tử trừ phần tử cuối cùng. Và tôi đã phải lặp thông qua các chỉ số của list và check mỗi lần lặp xem có phải là phần tử cuối cùng không.

    Tôi đã nhận thấy rằng đó là thứ tệ nhất tôi từng làm, nên tôi tìm hiểu về cách để lấy toàn bộ list trừ phần tử cuối. Và đó là khi tôi bắt đầu với slicing.

    # Không nên  
    for index in range(len(list4)):  
        if (index != len(list4)-1):  
            # Code here
    
    # Nên  
    for element in list4[:-1]:  
        # Code here  
    

    Trong một list có N phần tử thì phần tử cuối cùng, tức là phần tử thứ N-1 thì sẽ có chỉ số là -1, tương tự phần tử thứ N-2 có chỉ số là -2.

    Giả sử cho trước list1, chúng ta sẽ tạo ra một list2 mà sẽ lấy những phần tử con của list 1 bằng cú pháp tổng quát sau:

    list2 = list1[start:stop:step]

    Ở đây, nếu step không được khai báo thì nó sẽ có mặc định là +1, còn nếu một trong hai chỉ số start hoặc stop không được khai báo thì chúng sẽ có mặc định là 0.

    Việc hiểu về quy tắc sử dụng dấu hai chấm trong cú pháp slicing rất quan trọng. Trong đoạn code ở trên, tôi đã sử dụng [:-1] để chọn tất cả trừ phần tử cuối cùng trong list. Nếu tôi xóa dấu hai chấm đi hoặc đặt sang bên phải thì nó lại chỉ lấy phần tử cuối cùng của list.

    Đoạn code dưới chỉ rõ sự khác nhau của việc đặt vị trí dấu hai chấm.

    >>> list1 = [3,4,5,6,7,8]  
    >>> list1[2:4]  
    [5, 6]  
    >>> list1[2:]  
    [5, 6, 7, 8]  
    >>> list1[:4]  
    [3, 4, 5, 6]  
    >>> list1[::2]    #start = 0, stop = 0, step = 2        
    [3, 5, 7]  
    >>> list1[::-1]  
    [8, 7, 6, 5, 4, 3]  
    >>> list1[:5:2]  
    [3, 5, 7]  
    >>> list1[:4:2]  
    [3, 5]  
    

    Chú ý rằng [: :-1] chính là đảo ngược một list, và hãy kiểm tra việc slicing ở shell trước khi đưa vào script, đây là lý do khiến cho Python Shell trở nên rất tiện #2.

    6. Dictionary và Set

    Cho đến giờ list là cấu trúc dữ liệu được sử dụng nhiều nhất trong lập trình Python, nhưng tôi cũng sử dụng dictionary, set, và các cấu trúc dữ liệu khác cũng rất nhiều, vì những lợi ích của chúng.

    Một set đơn giản là một nơi chưa các phần tử, giống như list, nhưng chỉ giữ những phần tử riêng biệt, không giống nhau. Ví dụ, nếu thêm phần tử X và một set mà set đó đã có X thì set sẽ không thay đổi. Đây là thể là một lợi thế của set so với list, vì tôi thường không để ý đến sự trùng lặp khi làm việc với list, và để tạo một set dựa trên một list đã có sẵn thì dùng set(list_name)

    >>> example1 = [i for i in range(5)]  
    >>> example2 = [i for i in range(3,8)]  
    >>> example3 = example1 + example2  
    >>> example1  
    [0, 1, 2, 3, 4]  
    >>> example2  
    [3, 4, 5, 6, 7]  
    >>> example3  
    [0, 1, 2, 3, 4, 3, 4, 5, 6, 7]  
    >>> set_example1 = set(example3)  
    >>> set_example1  
    {0, 1, 2, 3, 4, 5, 6, 7}
    

    Tất nhiên nhược điểm của set so với list đó là set không hỗ trợ việc phân chỉ mục cho các phần tử, nên các phần tử sẽ không có thứ tự. Đây là một hạn chế khá lớn, nhưng không sao, nếu bạn không dùng đến chỉ mục và các phần tử lặp thì cứ dùng set.

    Ngoài set ra, tôi cũng nhận thấy dictionary cũng là một cấu trúc dữ liệu rất hữu dụng. Một dictionary là một sự liên kết của các key và value

    >>> dict_example = {'Bob' : 21, 'Chris' : 33, 'Dave' : 40}  
    >>> dict_example  
    {'Bob': 21, 'Dave': 40, 'Chris': 33}  
    >>> dict_example['Adam'] = 11  
    >>> dict_example  
    {'Adam': 11, 'Bob': 21, 'Dave': 40, 'Chris': 33}  
    >>> dict_example['Bob']  
    21  
    

    Có rất nhiều tình huống mà dict rất hữu dụng. Như là tìm giá trị thông qua key, đó là cách tìm thông tin rất hiệu quả. Vì vậy, dictionary là một trong những cấu trúc dữ liệu tối ưu nhất trong Python cơ bản.

    Phần 3


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới Cộng đồng Python Việt Nam, vui lòng đợi một lúc để chúng tôi thử kết nối lại.