Bài tập Enumerate & Zip - Nâng cao
- Viết hàm
enumerate_with_conditionchỉ enumerate phần tử thỏa điều kiện.
def enumerate_with_condition(lst, predicate): # Trả về list of (index, value) chỉ cho items thỏa predicate pass
# Testnumbers = [10, 25, 30, 15, 40, 5]result = enumerate_with_condition(numbers, lambda x: x > 20)print(result) # [(1, 25), (2, 30), (4, 40)]- Viết hàm
find_index_by_conditiontìm index đầu tiên thỏa điều kiện.
def find_index_by_condition(lst, predicate): # Trả về index hoặc -1 pass
# Testnumbers = [10, 15, 20, 25, 30]print(find_index_by_condition(numbers, lambda x: x > 20)) # 3- Viết hàm
enumerate_nestedenumerate nested list.
def enumerate_nested(nested_list): # Trả về (outer_index, inner_index, value) pass
# Testmatrix = [[1, 2], [3, 4], [5, 6]]for outer, inner, value in enumerate_nested(matrix): print(f"[{outer}][{inner}] = {value}")# [0][0] = 1# [0][1] = 2# [1][0] = 3# ...- Viết hàm
rank_scoresxếp hạng điểm (giữ index gốc).
def rank_scores(scores): # Trả về list of (rank, original_index, score) pass
# Testscores = [85, 95, 78, 92]result = rank_scores(scores)print(result)# [(1, 1, 95), (2, 3, 92), (3, 0, 85), (4, 2, 78)]- Viết hàm
sliding_window_enumeratetạo sliding windows với index.
def sliding_window_enumerate(lst, window_size): # Trả về (start_index, window) pass
# Testnumbers = [1, 2, 3, 4, 5]for index, window in sliding_window_enumerate(numbers, 3): print(f"{index}: {window}")# 0: [1, 2, 3]# 1: [2, 3, 4]# 2: [3, 4, 5]- Viết hàm
zip_with_defaultzip lists với giá trị mặc định khi hết.
def zip_with_default(*lists, default=None): # Giống zip_longest nhưng tự implement pass
# Testlist1 = [1, 2, 3]list2 = [4, 5]result = list(zip_with_default(list1, list2, default=0))print(result) # [(1, 4), (2, 5), (3, 0)]- Viết hàm
zip_dictzip nhiều dictionaries theo keys.
def zip_dict(*dicts): # Kết hợp values của cùng key pass
# Testdict1 = {"a": 1, "b": 2}dict2 = {"a": 10, "b": 20}dict3 = {"a": 100, "b": 200}result = zip_dict(dict1, dict2, dict3)print(result)# {'a': (1, 10, 100), 'b': (2, 20, 200)}- Viết hàm
transpose_list_of_dictschuyển đổi list of dicts sang dict of lists.
def transpose_list_of_dicts(records): # Dùng zip() pass
# Testrecords = [ {"name": "Alice", "age": 25, "city": "Hanoi"}, {"name": "Bob", "age": 30, "city": "HCMC"}]result = transpose_list_of_dicts(records)print(result)# {# 'name': ['Alice', 'Bob'],# 'age': [25, 30],# 'city': ['Hanoi', 'HCMC']# }- Viết hàm
parallel_maxtìm max của từng cột trong nhiều lists.
def parallel_max(*lists): # Trả về list max của từng vị trí pass
# Testlist1 = [1, 5, 3, 9]list2 = [4, 2, 8, 6]list3 = [3, 7, 2, 5]print(parallel_max(list1, list2, list3))# [4, 7, 8, 9]- Viết hàm
enumerate_with_groupsnhóm consecutive items.
def enumerate_with_groups(lst): # Trả về (group_num, items_in_group) # Group thay đổi khi giá trị thay đổi pass
# Testnumbers = [1, 1, 1, 2, 2, 3, 3, 3, 3]for group_id, items in enumerate_with_groups(numbers): print(f"Group {group_id}: {items}")# Group 0: [1, 1, 1]# Group 1: [2, 2]# Group 2: [3, 3, 3, 3]- Viết hàm
zip_longest_customtự implement zip_longest.
def zip_longest_custom(*iterables, fillvalue=None): # Không dùng itertools.zip_longest pass
# Testlist1 = [1, 2, 3]list2 = ['a', 'b']result = list(zip_longest_custom(list1, list2, fillvalue='?'))print(result) # [(1, 'a'), (2, 'b'), (3, '?')]- Viết hàm
merge_sorted_lists_indexedmerge sorted lists và giữ index gốc.
def merge_sorted_lists_indexed(list1, list2): # Trả về merged list với (value, source_list, original_index) pass
# Testlist1 = [1, 3, 5]list2 = [2, 4, 6]result = merge_sorted_lists_indexed(list1, list2)print(result)# [(1, 'list1', 0), (2, 'list2', 0), (3, 'list1', 1), ...]- Viết hàm
enumerate_with_prev_nextenumerate với previous và next value.
def enumerate_with_prev_next(lst): # Trả về (index, prev, current, next) pass
# Testnumbers = [10, 20, 30, 40, 50]for i, prev, curr, next in enumerate_with_prev_next(numbers): print(f"{i}: prev={prev}, curr={curr}, next={next}")# 0: prev=None, curr=10, next=20# 1: prev=10, curr=20, next=30# ...# 4: prev=40, curr=50, next=None- Viết hàm
zip_with_operationáp dụng operation cho mỗi cặp.
def zip_with_operation(list1, list2, operation): # operation: function nhận 2 params pass
# Testlist1 = [1, 2, 3, 4]list2 = [10, 20, 30, 40]result = zip_with_operation(list1, list2, lambda a, b: a * b)print(result) # [10, 40, 90, 160]- Viết hàm
find_differences_indexedtìm vị trí khác nhau giữa 2 lists.
def find_differences_indexed(list1, list2): # Trả về list of (index, value1, value2) pass
# Testlist1 = [1, 2, 3, 4, 5]list2 = [1, 5, 3, 8, 5]result = find_differences_indexed(list1, list2)print(result) # [(1, 2, 5), (3, 4, 8)]- Viết hàm
enumerate_chunksenumerate theo chunks.
def enumerate_chunks(lst, chunk_size): # Trả về (chunk_index, chunk) pass
# Testnumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]for index, chunk in enumerate_chunks(numbers, 3): print(f"Chunk {index}: {chunk}")# Chunk 0: [1, 2, 3]# Chunk 1: [4, 5, 6]# Chunk 2: [7, 8, 9]- Viết hàm
parallel_statisticstính statistics cho nhiều lists.
def parallel_statistics(*lists): # Trả về dict with min, max, avg cho từng position pass
# Testlist1 = [10, 20, 30]list2 = [15, 25, 35]list3 = [12, 22, 32]result = parallel_statistics(list1, list2, list3)print(result)# [# {'min': 10, 'max': 15, 'avg': 12.33},# {'min': 20, 'max': 25, 'avg': 22.33},# {'min': 30, 'max': 35, 'avg': 32.33}# ]- Viết hàm
cyclic_zipzip với cycling (lặp lại list ngắn hơn).
def cyclic_zip(list1, list2): # List ngắn hơn sẽ lặp lại pass
# Testlist1 = [1, 2, 3, 4, 5, 6]list2 = ['a', 'b']result = list(cyclic_zip(list1, list2))print(result)# [(1, 'a'), (2, 'b'), (3, 'a'), (4, 'b'), (5, 'a'), (6, 'b')]💡 Gợi ý: Dùng itertools.cycle()
- Viết hàm
enumerate_alternatingenumerate nhóm chẵn/lẻ riêng.
def enumerate_alternating(lst): # Trả về (even_index, odd_index, value) pass
# Testnumbers = [10, 20, 30, 40, 50, 60]for ei, oi, val in enumerate_alternating(numbers): print(f"even_idx={ei}, odd_idx={oi}, value={val}")# even_idx=0, odd_idx=None, value=10# even_idx=None, odd_idx=0, value=20# even_idx=1, odd_idx=None, value=30# ...- Viết hàm
weighted_average_paralleltính weighted average.
def weighted_average_parallel(values_lists, weights): # values_lists: list of lists # weights: list of weights # Trả về list weighted averages pass
# Testmath = [80, 90, 70]english = [85, 88, 75]science = [90, 85, 80]weights = [0.4, 0.3, 0.3]
result = weighted_average_parallel([math, english, science], weights)print(result)# [84.5, 87.9, 74.5]- Viết hàm
enumerate_skipenumerate với skip pattern.
def enumerate_skip(lst, skip=1): # skip=1: lấy mọi phần tử, skip=2: lấy 1 bỏ 1, etc. pass
# Testnumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]for index, value in enumerate_skip(numbers, skip=2): print(f"{index}: {value}")# 0: 1# 2: 3# 4: 5# ...- Viết hàm
zip_matrix_columnszip columns của matrix.
def zip_matrix_columns(matrix): # Trả về list of columns pass
# Testmatrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]result = zip_matrix_columns(matrix)print(result)# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]- Viết hàm
enumerate_with_running_totalenumerate với running total.
def enumerate_with_running_total(lst): # Trả về (index, value, running_total) pass
# Testnumbers = [10, 20, 30, 40, 50]for idx, val, total in enumerate_with_running_total(numbers): print(f"{idx}: value={val}, total={total}")# 0: value=10, total=10# 1: value=20, total=30# 2: value=30, total=60# ...- Viết hàm
parallel_filterfilter nhiều lists cùng lúc.
def parallel_filter(predicate, *lists): # Giữ items ở vị trí thỏa predicate pass
# Testlist1 = [1, 2, 3, 4, 5]list2 = [10, 20, 30, 40, 50]list3 = ['a', 'b', 'c', 'd', 'e']
# Chỉ giữ positions where list1[i] % 2 == 0filtered = parallel_filter(lambda x, y, z: x % 2 == 0, list1, list2, list3)print(filtered)# ([2, 4], [20, 40], ['b', 'd'])- Viết hàm
enumerate_hierarchicalenumerate cho hierarchical data.
def enumerate_hierarchical(data, level=0): # data: nested list/dict structure # Trả về (level, path, value) pass
# Testdata = { "root": { "child1": [1, 2, 3], "child2": { "grandchild": [4, 5] } }}
for level, path, value in enumerate_hierarchical(data): print(f"Level {level}: {path} = {value}")- Viết hàm
zip_with_index_mappingtạo mapping giữa indices của 2 sorted lists.
def zip_with_index_mapping(sorted_list1, sorted_list2): # Tìm matching elements và map indices pass
# Testlist1 = [1, 3, 5, 7, 9]list2 = [2, 3, 5, 8, 9]result = zip_with_index_mapping(list1, list2)print(result)# {(1, 1): 3, (2, 2): 5, (4, 4): 9}- Viết hàm
rolling_window_enumerateenumerate với rolling statistics.
def rolling_window_enumerate(lst, window_size, func): # Áp dụng func cho từng window # Trả về (index, window, result) pass
# Testnumbers = [1, 2, 3, 4, 5, 6, 7, 8]for idx, window, avg in rolling_window_enumerate(numbers, 3, lambda w: sum(w)/len(w)): print(f"{idx}: {window} -> avg={avg:.1f}")# 0: [1, 2, 3] -> avg=2.0# 1: [2, 3, 4] -> avg=3.0# ...- Viết hàm
enumerate_with_contextenumerate với context (n items trước/sau).
def enumerate_with_context(lst, context_size=1): # Trả về (index, context_before, current, context_after) pass
# Testnumbers = [10, 20, 30, 40, 50]for idx, before, curr, after in enumerate_with_context(numbers, context_size=1): print(f"{idx}: before={before}, curr={curr}, after={after}")# 0: before=[], curr=10, after=[20]# 1: before=[10], curr=20, after=[30]# ...- Viết hàm
multi_column_sort_enumeratesort và enumerate với multiple keys.
def multi_column_sort_enumerate(data, *sort_keys): # data: list of dicts # sort_keys: list of keys to sort by # Trả về sorted data với original indices pass
# Teststudents = [ {"name": "Alice", "class": "A", "score": 85}, {"name": "Bob", "class": "B", "score": 85}, {"name": "Charlie", "class": "A", "score": 90}]
for orig_idx, student in multi_column_sort_enumerate(students, "score", "name"): print(f"Original index {orig_idx}: {student}")- Viết hàm
lazy_enumerate_ziptạo generator kết hợp enumerate và zip.
def lazy_enumerate_zip(*lists, start=0): # Generator function # Trả về (index, (item1, item2, ...)) pass
# Testlist1 = [1, 2, 3]list2 = ['a', 'b', 'c']list3 = [10, 20, 30]
for idx, (num, letter, val) in lazy_enumerate_zip(list1, list2, list3): print(f"{idx}: {num}, {letter}, {val}")# 0: 1, a, 10# 1: 2, b, 20# 2: 3, c, 30