Tên và danh sách được tách bằng hai loại dấu
Bài thực hành dùng dữ liệu tài khoản, liên hệ và nhóm **giả định** trong các tệp mẫu. Mỗi dòng gồm tên, một dấu hai chấm rồi danh sách các phần tử ngăn bằng dấu phẩy. Ví dụ tệp liên hệ:
```text
Mẫu A: P1, P2, P3, P4
Mẫu B: P2, P3, P4, P5
Mẫu C: P3, P5
Mẫu D:
```
Dòng cuối có tài khoản Mẫu D nhưng chưa có phần tử liên hệ nào. Sau khi đọc, names và lists có cùng độ dài; names[i] và lists[i] thuộc cùng một tài khoản. Tệp nhóm dùng cùng cấu trúc nhưng từng phần tử là tên nhóm, như “Lập trình”, “Đọc sách”.
Làm sạch khoảng trắng và giữ liên hệ theo chỉ số
```python
def read_lists(filename):
names, lists = [], []
with open(filename, encoding='utf-8') as source:
for number, line in enumerate(source, 1):
if not line.strip():
continue
if line.count(':') != 1:
raise ValueError(f'Dòng {number}: cần một dấu hai chấm.')
name, raw = line.split(':', 1)
name = name.strip()
if not name or name in names:
raise ValueError(f'Dòng {number}: tên trống hoặc trùng.')
values = [x.strip() for x in raw.split(',')] if raw.strip() else []
if any(not x for x in values) or len(values) != len(set(values)):
raise ValueError(f'Dòng {number}: phần tử trống hoặc trùng.')
names.append(name)
lists.append(values)
return names, lists
```
Hàm đọc UTF-8 để giữ chữ có dấu. strip bỏ khoảng trắng ở hai đầu tên/phần tử; tên có nhiều từ vẫn là một tên. Mỗi dòng hợp lệ phải thêm đồng thời tên vào names và danh sách vào lists. Sau dấu hai chấm không có dữ liệu thì tạo[], không tạo một phần tử chuỗi rỗng.
Mỗi tên tài khoản là duy nhất, từng danh sách không lặp phần tử. Tệp tải kiểm các điều kiện ấy để tránh đếm cùng một liên hệ hoặc nhóm nhiều lần. Dòng thiếu dấu phân cách, tên trống/trùng, phần tử trống/trùng sẽ báo lỗi kèm số dòng. Mỗi dòng trắng được bỏ qua.
Bài luyện
Dòng “Mẫu D:” cần tạo danh sách nào cho Mẫu D?
Tên tài khoản không tự là phần tử liên hệ của nó.
Cần giữ tên và danh sách tương ứng.
Có tài khoản nhưng không có phần tử trong danh sách.
Chuỗi rỗng không phải một liên hệ hợp lệ.
Lời giải
Tên trước dấu hai chấm vẫn tồn tại. Phần sau trống biểu diễn không có phần tử, nên thêm tên Mẫu D và danh sách[] ở cùng chỉ số.
Bài luyện
Vì sao phải thêm cả names.append(name) và lists.append(values)?
Mỗi dòng chỉ tạo một tài khoản và một danh sách.
Không có thao tác sắp xếp ở đây.
Phải giữ riêng tên và các phần tử.
Hai dãy cần đi cùng nhau khi tìm vị trí tên.
Lời giải
Bước tìm tên trả chỉ số i. Chỉ khi hai dãy được thêm tương ứng, lists[i] mới đúng là dữ liệu thuộc names[i].
Bài luyện
Vì sao dữ liệu mỗi danh sách không được lặp cùng một tên nhóm?
Một nhóm chỉ tính một lần trong quan hệ tham gia.
UTF-8 đang hỗ trợ chữ có dấu.
Có thể có nhiều nhóm khác nhau.
Đọc cấu trúc này không cần sắp xếp.
Lời giải
Thuật toán duyệt các phần tử của danh sách đầu. Nếu một nhóm bị ghi hai lần, nó có thể được cộng hai lần dù chỉ là một nhóm; cần dữ liệu không trùng hoặc xử lí trùng trước.
Đang học