---
# System prepended metadata

title: Virgil - Practice Python - S32 List Tuple Loops
tags: [' LearnWorld', ' PracticePython', Virgil]

---

---
title: Virgil - Practice Python - S32 List Tuple Loops
tags: Virgil, LearnWorld, PracticePython
---

# List, Tuple, and Loops

## List

List trong Python là một chuỗi có thứ tự các giá trị. List được định nghĩa bằng dấu ngoặc vuông `[]` và các giá trị cách nhau bởi dấu `,`:

```python
primes = [2, 3, 5, 7]
```

List có thể nằm trong một list khác:

```python
hands = [
    ['J', 'Q', 'K'],
    ['2', '2', '2'],
    ['6', 'A', 'K'], # (Comma after the last element is optional)
]

# (Alternative way, but it can get hard to read)
hands = [['J', 'Q', 'K'], ['2', '2', '2'], ['6', 'A', 'K']]
```

List có thể chứa các giá trị có kiểu dữ liệu (datatype) khác nhau:

```python
my_favourite_things = [32, 'Always be learning!', help]
# Look! There is a help() function at the end
```

### Indexing

List Indexing là khái niệm truy xuất phần tử trong một list theo số thứ tự.

```python
planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']

print(planets[0])  # Output: Mercury
```

Trong Python số thứ tự bắt đầu từ 0, nên `planets[0]` là giá trị đầu tiên trong list `Mercury`. Như vậy `Venus` có index là 1 và `Earth` có thể được truy cập bằng `planets[2]`.

Python cho phép index là số âm. Index âm truy cập đến phần tử cuối của list với phần tử cuối cùng có index là -1 (`Neptune`), tiếp theo index -2 là `Uranus`.

### Slicing

List Slicing là việc lấy ra một phần (có thể là toàn bộ) list. Ví dụ nếu muốn lấy 3 phần tử đầu tiên của list `planets`:

```python
planets[0:3]  # Result: ['Mercury', 'Venus', 'Earth']

# or

planets[:3]  # Result: ['Mercury', 'Venus', 'Earth']
```

Cú pháp `0:3` có nghĩa là lấy phần tử bắt đầu từ index 0 cho tới index trước 3 (**không lấy phần tử index 3**). Python cho phép viết tắt nếu số bên trái dấu `:` là 0 bằng cách bỏ nó đi, nên hai cách viết ở trên là như nhau.

Tương tự số bên phải dấu `:` cũng có thể lược bỏ, trong trường hợp đó nghĩa là lấy tới phần tử cuối cùng của list:

```python
planets[3:]  # Result: ['Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
```

Slicing cho phép sử dụng index âm:

```python
# All the planets except the first and last
planets[1:-1]

# The last 3 planets
planets[-3:]
```

**Bước nhảy trong slicing**: Theo mặc định sau khi định nghĩa điểm đầu và cuối như trên, slicing sẽ lấy các phần tử nối tiếp nhau. Bạn cũng có thể định nghĩa lấy 2 phần tử một, ví dụ:

```python
lst = [1, 2, 3, 4, 5, 6, 7, 8]
print(lst[1::2])  # Output: [2, 4, 6, 8]
```

Trong ví dụ trên,

- Dấu `:` đầu tiên định nghĩa hai điểm đầu, cuối từ 1 đến hết (do phía bên phải không có index)
- Dấu `:` thứ 2 định nghĩa bước nhảy 2 (lấy 2 phần tử một)

_Indexing và Slicing rất quan trọng và được sử dụng thường xuyên, do khi lập trình bạn thường làm việc với dữ liệu được lưu dưới dạng list_

### Các function đi kèm với list

Python có một vài function rất hữu dụng cho list:

- `len()` trả về chiều dài một list:

```python
# How many planets are there?
len(planets)
```

- `sorted()` sắp xếp các phần tử trong list:

```python
# The planets sorted in descending alphabetical order
sorted(planets, reverse=False)
```

- `sum()` tính tổng các phần tử trong list:

```python
prime = [2, 3, 5, 7]
print(sum(prime))  # Output: 17
```

- `min()` và `max()` trả về phần tử nhỏ nhất và lớn nhất trong list

```python
print(min(prime), max(prime))  # Output: 2, 7
```

### Các methods của list

```python
l = ['a','b','c']
l.append('d')
print(l)  # Output ['a', 'b', 'c', 'd']
```

Trong ví dụ trên `append()` là cách bạn đưa thêm phần tử mới `d` vào list `l`. `append()` được gọi là method của list `l`. Về cơ bản methods chính là một function.

Sự khác biệt giữa function và method là cách chúng được gọi, bạn có thể thấy method được gọi bằng `l.append('d')`. Method `append` thuộc về list `l` và nó được gọi thông qua list `l`. Kết quả của method `append` tác động trực tiếp và list `l`.

Khái niệm method thuộc về lĩnh vực lập trình hướng đối tượng OOP (Object-oriented programming). Bạn có thể học cách sử dụng trước khi đi sâu vào hiểu khái niệm này sau.

Một vài methods khác:

- `list.pop()` loại bỏ phần tử cuối của list và trả về giá trị phần tử đó:

```python
l = [1, 2, 3, 4]
last_element = l.pop()
print(l)  # Output [1, 2, 3]
print(last_element)  # Output 4
```

- `list.index(value)` trả về index của giá trị value trong list, Python sẽ báo lỗi nếu giá trị value không nằm trong list:

```python
l = [1, 2, 3, 4]
l.index(2)  # Result: 1
```

Để tìm hiểu thêm các methods khác, bạn có thể chạy `help(l)` để đọc docstring của list (Lưu ý, bạn phải tạo list `l` trước khi sử dụng `help(l)`).

## Tuple

Tuple là trường hợp đặc biệt của list. Về cơ bản tuple giống hệt list. Có vài điểm khác biệt là:

- Tuple định nghĩa bởi dấu ngoặc tròn thay vì ngoặc vuông như list `()`
- Các phần tử trong tuple không thể bị thay đổi.
- Tuple hoạt động nhanh hơn list.

```python
t = (1, 2, 3)
t[0] = 100  # TypeError: 'tuple' object does not support item assignment
```

Chúng ta sử dụng tuple khi muốn bảo vệ dữ liệu không bị thay đổi, hoặc tạo danh sách hằng số sử dụng trong chương trình.

## Loops

Loops (vòng lặp) được dùng khi bạn có những đoạn code cần chạy lặp lại nhiều lần. Loops thường đi kèm với list để duyệt qua các phần tử trong list.

### The `for` loop

```python
planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']

for planet in planets:
    print(planet, end=' ') # print all on same line
```

Trong ví dụ trên:

- `planets` là danh sách chứa các giá trị sẽ được duyệt qua
- `planet` là biến được dùng để đại diện một phần tử trong list `planets`
- `in` là từ khoá kết nối chúng lại với nhau

Trong trường hợp bạn chỉ muốn chạy code một số lần nhất định, bạn dùng function `range()`:

```python
for i in range(5):
    print('i = ', i)
```

### The `while` loop

Vòng lặp `while` sẽ lặp lại cho đến khi điều kiện đầu vào sai:

```python
i = 0
while i < 5:
    print(i, end=' ')
    i += 1
```

Trong ví dụ trên:

- Điều kiện `i < 5` là một biểu thức logic, ban đầu khi `i` có giá trị bằng 0 thì biểu thức đúng, các câu lệnh trong vòng lặp `while` sẽ được thực thi
- Mỗi lần code trong while được thực thi, câu lệnh `i += 1` (cách viết tắt của `i = i + 1`) sẽ tăng giá trị của i thêm 1.
- Cho đến khi `i` đạt giá trị 5, điều kiện `i < 5` sẽ bị sai và vòng lặp `while` kết thúc.

Lưu ý, vòng lặp `while` có thể chạy đến vô hạn nếu điều kiện đầu vào không bao giờ sai.

## Nâng cao và mở rộng

- Bạn có thể đảo chiều các phần tử của list bằng slicing:

```python
lst = [1, 2, 3, 4, 5]
print(lst[::-1])  # Output: [5, 4, 3, 2, 1]
```

- Bạn có thể kiểm tra một giá trị có nằm trong list không bằng từ khoá `in`:

```python
l = [1, 2, 3]

if 2 in l:
    print('2 is an element of l')
else:
    print('2 is not in l')
```

- **List comprehension** là một cách rút gọn code rất được ưa chuộng trong Python. Cú pháp của nó là:

```python
[ expression for item in list if conditional ]
```

Ví dụ:

```python
# List of even numbers from 0 to 100: 0, 2, 4, 6, 8,...
even_numbers = [i for i in range(100) if i % 2 == 0]

# List of square numbers: 0, 1, 4, 9, 16, ..., 100
squares = [x*x for x in range(10)]
```

List comprehension có thể rút gọn một đoạn code về một dòng lệnh. Xem xét function dưới đây:

```python
def count_negatives(nums):
    """Return the number of negative numbers in the given list.

    >>> count_negatives([5, -1, -2, 0, 3])
    2
    """
    n_negative = 0
    for num in nums:
        if num < 0:
            n_negative = n_negative + 1
    return n_negative
```

Function `count_negatives` đếm số các số âm trong một list là tham số đầu vào. Chúng ta có thể rút gọn code dùng list comprehension như sau:

```python
def count_negatives(nums):
    return len([num for num in nums if num < 0])
```

Hoặc:

```python
def count_negatives(nums):
    return sum([num < 0 for num in nums])
```
