
列表和字典是 Python 里用得最多的两种数据结构,但真正用熟的人不多。下面这 40 个技巧,从切片到深层合并,挑你用得上的记就行。
往期阅读>>>
Python 20 个文本分析的库:效率提升 10 倍的秘密武器
Python 自动化管理Jenkins的15个实用脚本,提升效率
App2Docker:如何无需编写Dockerfile也可以创建容器镜像
Python 自动化识别Nginx配置并导出为excel文件,提升Nginx管理效率
# 传统写法ifx>5andx<10:print("在范围内")# 链式比较if5<x<10:print("在范围内")
# 带条件判断的列表推导式numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]even_squares = [x**2forxinnumbersifx%2 == 0]print(even_squares) # [4, 16, 36, 64, 100]# 嵌套列表推导式matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flattened = [numforrowinmatrixfornuminrow]print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 反转列表my_list = [1, 2, 3, 4, 5]reversed_list = my_list[::-1]print(reversed_list) # [5, 4, 3, 2, 1]# 获取最后n个元素last_three = my_list[-3:]print(last_three) # [3, 4, 5]# 间隔取元素every_other = my_list[::2]print(every_other) # [1, 3, 5]
# 使用*操作符合并列表list1 = [1, 2, 3]list2 = [4, 5, 6]merged = [*list1, *list2]print(merged) # [1, 2, 3, 4, 5, 6]# 嵌套列表展开nested = [[1, 2], [3, 4], [5, 6]]flattened = sum(nested, [])print(flattened) # [1, 2, 3, 4, 5, 6]
# 创建平方字典numbers = [1, 2, 3, 4, 5]square_dict = {x: x**2forxinnumbers}print(square_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 带条件过滤even_squares = {x: x**2forxinnumbersifx%2 == 0}print(even_squares) # {2: 4, 4: 16}
# Python 3.9+ 使用 | 操作符dict1 = {'a': 1, 'b': 2}dict2 = {'c': 3, 'd': 4}merged = dict1|dict2print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}# 传统合并方法merged = {**dict1, **dict2}
fromcollectionsimportdefaultdict# 使用defaultdictword_count = defaultdict(int)words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']forwordinwords:word_count[word] += 1print(dict(word_count)) # {'apple': 3, 'banana': 2, 'orange': 1}
original = {'a': 1, 'b': 2, 'c': 3}reversed_dict = {v: kfork, vinoriginal.items()}print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
fromitertoolsimportgroupbydata = [ {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 25}, {'name': 'David', 'age': 30}]# 按年龄分组data.sort(key=lambdax: x['age'])grouped = {k: list(v) fork, vingroupby(data, key=lambdax: x['age'])}print(grouped)# {25: [{'name': 'Alice', 'age': 25}, {'name': 'Charlie', 'age': 25}],# 30: [{'name': 'Bob', 'age': 30}, {'name': 'David', 'age': 30}]}
fromcollectionsimportCounteritems = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']frequency = Counter(items)print(frequency) # Counter({'apple': 3, 'banana': 2, 'orange': 1})print(frequency.most_common(2)) # [('apple', 3), ('banana', 2)]
# 列表推导式(占用内存)large_list = [x**2forxinrange(1000000)]# 生成器表达式(节省内存)large_gen = (x**2forxinrange(1000000))# 使用时forvalueinlarge_gen:# 处理每个值pass
fruits = ['apple', 'banana', 'orange']# 传统写法foriinrange(len(fruits)):print(f"{i}: {fruits[i]}")# 更Pythonic的写法fori, fruitinenumerate(fruits):print(f"{i}: {fruit}")# 指定起始索引fori, fruitinenumerate(fruits, start=1):print(f"{i}: {fruit}")
names = ['Alice', 'Bob', 'Charlie']ages = [25, 30, 35]cities = ['New York', 'London', 'Paris']forname, age, cityinzip(names, ages, cities):print(f"{name} is {age} years old and lives in {city}")
defbinary_search(arr, target):left, right = 0, len(arr) -1whileleft<= right:mid = (left+right) //2ifarr[mid] == target:returnmidelifarr[mid] <target:left = mid+1else:right = mid-1return-1# 使用sorted_list = [1, 3, 5, 7, 9, 11, 13]result = binary_search(sorted_list, 7)print(f"找到元素,索引为: {result}") # 3
deffibonacci_generator(n):a, b = 0, 1count = 0whilecount<n:yieldaa, b = b, a+bcount += 1# 使用fib_nums = list(fibonacci_generator(10))print(fib_nums) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
defremove_duplicates_preserve_order(items):seen = set()result = []foriteminitems:ifitemnotinseen:seen.add(item)result.append(item)returnresult# 使用duplicate_list = [3, 1, 2, 1, 4, 3, 5, 2]unique_list = remove_duplicates_preserve_order(duplicate_list)print(unique_list) # [3, 1, 2, 4, 5]
scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'David': 95}# 按值升序排序sorted_by_value = dict(sorted(scores.items(), key=lambdax: x[1]))print(sorted_by_value) # {'Charlie': 78, 'Alice': 85, 'Bob': 92, 'David': 95}# 按值降序排序sorted_desc = dict(sorted(scores.items(), key=lambdax: x[1], reverse=True))print(sorted_desc)# {'David': 95, 'Bob': 92, 'Alice': 85, 'Charlie': 78}
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 使用map进行转换squares = list(map(lambdax: x**2, numbers))print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 使用filter进行过滤evens = list(filter(lambdax: x%2 == 0, numbers))print(evens) # [2, 4, 6, 8, 10]# 组合使用even_squares = list(map(lambdax: x**2, filter(lambdax: x%2 == 0, numbers)))print(even_squares) # [4, 16, 36, 64, 100]
fromfunctoolsimportreducenumbers = [1, 2, 3, 4, 5]# 计算乘积product = reduce(lambdax, y: x*y, numbers)print(f"乘积: {product}") # 120# 计算最大值max_value = reduce(lambdax, y: xifx>yelsey, numbers)print(f"最大值: {max_value}") # 5
user_data = {'name': 'Alice', 'age': 25}# 安全获取不存在的键email = user_data.get('email', '未提供')print(f"邮箱: {email}") # 邮箱: 未提供# 使用setdefault设置默认值user_data.setdefault('country', '中国')print(user_data) # {'name': 'Alice', 'age': 25, 'country': '中国'}
numbers = [1, 3, 5, 7, 9]has_even = any(x%2 == 0forxinnumbers)print(f"是否有偶数: {has_even}") # Falseall_positive = all(x>0forxinnumbers)print(f"是否都为正数: {all_positive}") # True
defrotate_list(lst, k):"""将列表元素向右旋转k个位置"""k = k%len(lst) # 处理k大于列表长度的情况returnlst[-k:] +lst[:-k]my_list = [1, 2, 3, 4, 5]rotated = rotate_list(my_list, 2)print(f"旋转后: {rotated}") # [4, 5, 1, 2, 3]
defswap_dict_with_duplicates(original):"""处理有重复值的字典键值交换"""result = {}forkey, valueinoriginal.items():ifvaluenotinresult:result[value] = [key]else:result[value].append(key)returnresultoriginal = {'a': 1, 'b': 2, 'c': 1, 'd': 3}swapped = swap_dict_with_duplicates(original)print(swapped) # {1: ['a', 'c'], 2: ['b'], 3: ['d']}
defchunk_list(lst, chunk_size):"""将列表分成指定大小的块"""return [lst[i:i+chunk_size] foriinrange(0, len(lst), chunk_size)]numbers = list(range(1, 11))chunks = chunk_list(numbers, 3)print(f"分块结果: {chunks}") # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
defget_keys_sorted_by_value(dictionary, reverse=False):"""根据值排序并返回对应的键"""return [kfork, vinsorted(dictionary.items(), key=lambdax: x[1], reverse=reverse)]scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'David': 95}sorted_keys = get_keys_sorted_by_value(scores, reverse=True)print(f"按分数降序排列的名字: {sorted_keys}") # ['David', 'Bob', 'Alice', 'Charlie']
deffrequency_count(lst):"""手动实现元素频率统计"""freq = {}foriteminlst:freq[item] = freq.get(item, 0) +1returnfreqitems = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']freq = frequency_count(items)print(f"元素频率: {freq}") # {'apple': 3, 'banana': 2, 'orange': 1}
defdeep_merge_dicts(dict1, dict2):"""深度合并两个字典,处理嵌套字典"""result = dict1.copy()forkey, valueindict2.items():ifkeyinresultandisinstance(result[key], dict) andisinstance(value, dict):result[key] = deep_merge_dicts(result[key], value)else:result[key] = valuereturnresultdict1 = {'a': 1, 'b': {'x': 10, 'y': 20}}dict2 = {'b': {'y': 30, 'z': 40}, 'c': 3}merged = deep_merge_dicts(dict1, dict2)print(merged) # {'a': 1, 'b': {'x': 10, 'y': 30, 'z': 40}, 'c': 3}
defsliding_window(lst, window_size):"""生成滑动窗口"""foriinrange(len(lst) -window_size+1):yieldlst[i:i+window_size]numbers = [1, 2, 3, 4, 5, 6]windows = list(sliding_window(numbers, 3))print(f"滑动窗口: {windows}") # [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
defconvert_dict_types(dictionary, key_type=str, value_type=int):"""转换字典键值的类型"""return {key_type(k): value_type(v) fork, vindictionary.items()}original = {'1': '10', '2': '20', '3': '30'}converted = convert_dict_types(original, key_type=int, value_type=int)print(f"转换后: {converted}") # {1: 10, 2: 20, 3: 30}
fromitertoolsimportpermutations, combinationsitems = ['A', 'B', 'C']perms = list(permutations(items, 2))print(f"排列结果: {perms}") # [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]combs = list(combinations(items, 2))print(f"组合结果: {combs}") # [('A', 'B'), ('A', 'C'), ('B', 'C')]
defextract_and_transform(dictionary, key_list, transform_func=None):"""提取指定键的值并应用转换函数"""result = []forkeyinkey_list:ifkeyindictionary:value = dictionary[key]iftransform_func:value = transform_func(value)result.append(value)returnresultdata = {'name': 'Alice', 'age': '25', 'score': '95.5'}keys = ['name', 'age', 'score']values = extract_and_transform(data, keys, transform_func=lambdax: x.upper() ifisinstance(x, str) elsex)print(f"提取并转换的值: {values}") # ['ALICE', '25', '95.5']
definterleave_lists(*lists):"""交错合并多个列表"""result = []max_len = max(len(lst) forlstinlists)foriinrange(max_len):forlstinlists:ifi<len(lst):result.append(lst[i])returnresultlist1 = [1, 2, 3]list2 = ['A', 'B', 'C']list3 = ['x', 'y', 'z']interleaved = interleave_lists(list1, list2, list3)print(f"交错合并结果: {interleaved}") # [1, 'A', 'x', 2, 'B', 'y', 3, 'C', 'z']
deffilter_dict_by_condition(dictionary, condition_func):"""根据条件过滤字典键值对"""return {k: vfork, vindictionary.items() ifcondition_func(k, v)}data = {'apple': 5, 'banana': 3, 'orange': 8, 'grape': 2}# 过滤值大于3的项filtered = filter_dict_by_condition(data, lambdak, v: v>3)print(f"过滤结果: {filtered}") # {'apple': 5, 'orange': 8}# 过滤键包含'a'的项filtered_by_key = filter_dict_by_condition(data, lambdak, v: 'a'ink)print(f"按键过滤结果: {filtered_by_key}") # {'apple': 5, 'banana': 3, 'grape': 2}
defrunning_sum(lst):"""计算列表元素的运行总和"""total = 0result = []fornuminlst:total += numresult.append(total)returnresultnumbers = [1, 2, 3, 4, 5]sums = running_sum(numbers)print(f"运行总和: {sums}") # [1, 3, 6, 10, 15]
defbatch_update_dict(original, updates):"""批量更新字典,支持嵌套键"""result = original.copy()forkey_path, valueinupdates.items():if'.'inkey_path:# 处理嵌套键keys = key_path.split('.')current = resultforkinkeys[:-1]:current = current.setdefault(k, {})current[keys[-1]] = valueelse:result[key_path] = valuereturnresultuser = {'name': 'Alice', 'profile': {'age': 25}}updates = {'name': 'Alice Smith', 'profile.age': 26, 'profile.city': 'Beijing'}updated = batch_update_dict(user, updates)print(updated) # {'name': 'Alice Smith', 'profile': {'age': 26, 'city': 'Beijing'}}
deffind_pattern(lst, pattern):"""在列表中查找特定模式"""pattern_len = len(pattern)matches = []foriinrange(len(lst) -pattern_len+1):iflst[i:i+pattern_len] == pattern:matches.append(i)returnmatchessequence = [1, 2, 3, 1, 2, 3, 4, 1, 2, 3]pattern = [1, 2, 3]positions = find_pattern(sequence, pattern)print(f"模式出现位置: {positions}") # [0, 3, 7]
defdict_summary(dictionary):"""生成字典值的统计摘要"""ifnotdictionary:return {}values = list(dictionary.values())numeric_values = [vforvinvaluesifisinstance(v, (int, float))]summary = {'count': len(dictionary),'keys': list(dictionary.keys()),'value_types': {type(v).__name__forvinvalues} }ifnumeric_values:summary.update({'min': min(numeric_values),'max': max(numeric_values),'sum': sum(numeric_values),'avg': sum(numeric_values) /len(numeric_values) })returnsummarydata = {'a': 10, 'b': 20, 'c': 30, 'd': 'text'}summary = dict_summary(data)print(f"字典摘要: {summary}")
deflist_differences(list1, list2):"""分析两个列表的差异"""set1, set2 = set(list1), set(list2)return {'only_in_list1': list(set1-set2),'only_in_list2': list(set2-set1),'common': list(set1&set2),'union': list(set1|set2) }list_a = [1, 2, 3, 4, 5]list_b = [4, 5, 6, 7, 8]diff = list_differences(list_a, list_b)print(f"列表差异分析: {diff}")
defget_nested_value(dictionary, key_path, default=None):"""通过点分隔的路径访问嵌套字典值"""keys = key_path.split('.')current = dictionaryforkeyinkeys:ifisinstance(current, dict) andkeyincurrent:current = current[key]else:returndefaultreturncurrentdata = {'user': {'profile': {'name': 'Alice','age': 25,'address': {'city': 'Beijing','zip': '100000' } } }}name = get_nested_value(data, 'user.profile.name')city = get_nested_value(data, 'user.profile.address.city')country = get_nested_value(data, 'user.profile.address.country', 'China')print(f"姓名: {name}") # Aliceprint(f"城市: {city}") # Beijingprint(f"国家: {country}") # China
importrandomdefweighted_random_choice(items, weights):"""根据权重随机选择列表元素"""iflen(items) != len(weights):raiseValueError("Items and weights must have the same length")total = sum(weights)r = random.uniform(0, total)cumulative = 0foritem, weightinzip(items, weights):cumulative += weightifr<= cumulative:returnitemreturnitems[-1] # 安全返回fruits = ['apple', 'banana', 'orange']weights = [0.5, 0.3, 0.2]# 模拟多次选择choices = [weighted_random_choice(fruits, weights) for_inrange(1000)]print(f"苹果出现次数: {choices.count('apple')}")print(f"香蕉出现次数: {choices.count('banana')}")print(f"橙子出现次数: {choices.count('orange')}")
40 个技巧不用全背,前 20 个属于高频场景,基本每天都能用到。21-40 更偏工具性,遇到对应问题时翻出来用比硬记更实际。itertools、collections、functools 这三个标准库模块值得单独花时间读一遍文档,收益很高。
