当前位置: 首页 > news >正文

Python常见面试题的详解8

1. 变量作用域和查找规则(LEGB)

  • 作用域层级
  1. Local:函数内部作用域

  2. Enclosing:闭包函数外层作用域

  3. Global:模块全局作用域

  4. Built-in:内置命名空间

  • 查找顺序:L → E → G → B
  • 关键特性

  global声明修改全局变量

  nonlocal修改闭包外层变量

      函数参数属于局部作用域

python

x = 'global'
def outer():
    x = 'outer'
    def inner():
        nonlocal x  # 修改闭包变量
        x = 'inner'
    inner()
    print(x)  # 输出 'inner'
  •  要点

Python 中有四种作用域:局部作用域(Local,L)、闭包函数外的函数中作用域(Enclosing,E)、全局作用域(Global,G)、内置作用域(Built - in,B)。变量查找顺序遵循 LEGB 规则,即先在局部作用域查找,若未找到则到闭包函数外的函数中作用域查找,接着是全局作用域,最后是内置作用域。在嵌套函数中,内层函数可以访问外层函数的变量,但默认情况下不能修改。如果需要修改,可以使用 nonlocal 关键字。在模块中定义的变量属于全局作用域,但在函数内部如果使用 global 关键字,可以修改全局变量的值。

  • 示例

python

def outer():
    x = 10
    def inner():
        nonlocal x
        x = 20
    inner()
    print(x)  # 输出 20

outer()

2. 用三种方式将字符串 "789" 转换成 789 ,不使用内置 api,例如 int() 

python

# 方法1:ASCII码计算
def str_to_int(s):
    num = 0
    for c in s:
        num = num*10 + (ord(c) - ord('0'))
    return num

# 方法2:逐位乘累加
def str_to_int(s):
    return sum((ord(c)-48)*10**i for i,c in enumerate(reversed(s)))

# 方法3:递归实现
def str_to_int(s, acc=0):
    return acc if not s else str_to_int(s[1:], acc*10 + (ord(s[0])-48))
  •  要点

可以使用 ASCII 码和乘法,加法运算,通过循环和位运算,使用递归这些方法可以实现对字符串和整数之间转换。在一些对性能要求较高且不允许使用内置函数的场景下,这些手动实现的转换方法会更有优势。

  • 示例

python

# 方法一:利用 ASCII 码和乘法、加法运算
def str_to_int_1(s):
    result = 0
    for char in s:
        result = result * 10 + (ord(char) - ord('0'))
    return result

# 方法二:通过循环和位运算
def str_to_int_2(s):
    num = 0
    for i in range(len(s)):
        digit = ord(s[i]) - ord('0')
        num = (num << 3) + (num << 1) + digit
    return num

# 方法三:使用递归
def str_to_int_3(s):
    if len(s) == 0:
        return 0
    return str_to_int_3(s[:-1]) * 10 + (ord(s[-1]) - ord('0'))

print(str_to_int_1("789"))
print(str_to_int_2("789"))
print(str_to_int_3("789"))

 

 3. 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

  •  要点
  1. 暴力枚举法,通过两层循环遍历数组,找到满足条件的两个数。
  2. 使用哈希表,遍历数组时,记录每个元素及其索引,同时检查目标值与当前元素的差值是否已在哈希表中。
  3. 在处理大规模数组时,哈希表的优势会更加明显。该问题还可以扩展到找出数组中三个数、四个数之和等于目标值的情况。
  • 示例

python

# 方法一:暴力枚举法
def twoSum_1(nums, target):
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            if nums[i] + nums[j] == target:
                return [i, j]

# 方法二:使用哈希表
def twoSum_2(nums, target):
    num_dict = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in num_dict:
            return [num_dict[complement], i]
        num_dict[num] = i

nums = [1, 2, 3, 4]
target = 3
print(twoSum_1(nums, target))
print(twoSum_2(nums, target))

 

4. 用三种方式统计一个文本中单词频次最高的 10 个单词

  • 要点
  1. 使用字典手动统计单词频次,然后对字典按值排序。
  2. 使用 collections.Counter 类,可以方便地统计元素的频次。
  3. 结合 defaultdictheapq 模块,利用堆排序找出前 10 个高频单词。
  4. 在处理大规模文本时,collections.Counter 是比较高效的选择,因为它的实现经过了优化。而使用 heapq 模块可以在不排序整个单词频次字典的情况下找出前 10 个高频单词,在内存使用上可能更有优势。

  • 示例

python

import collections
import heapq

text = "apple banana apple cherry banana apple"

# 方法一:使用字典手动统计
word_count = {}
for word in text.split():
    if word in word_count:
        word_count[word] += 1
    else:
        word_count[word] = 1
sorted_words = sorted(word_count.items(), key=lambda item: item[1], reverse=True)[:10]
print(sorted_words)

# 方法二:使用 collections.Counter
counter = collections.Counter(text.split())
print(counter.most_common(10))

# 方法三:结合 defaultdict 和 heapq
from collections import defaultdict
word_freq = defaultdict(int)
for word in text.split():
    word_freq[word] += 1
heap = [(-freq, word) for word, freq in word_freq.items()]
heapq.heapify(heap)
top_10 = [heapq.heappop(heap) for _ in range(min(10, len(heap)))]
result = [(word, -freq) for freq, word in top_10]
print(result)

 

5. 请写出一个函数满足以下条件:该函数的输入是一个仅包含数字的 list,输出一个新的 list,其中每一个元素要满足以下条件:

  1. 该元素是奇数
  2. 该元素在原 list 中是在奇数的位置(index 是奇数)
  •  要点

使用列表推导式遍历原列表,筛选出满足条件的元素。可以定义一个函数应用于数据处理中,例如从一系列测量数据中筛选出特定位置的奇数测量值。对于不同的数据类型或更复杂的筛选条件,可以对该函数进行扩展。

  • 示例

python

def filter_list(lst):
    return [lst[i] for i in range(1, len(lst), 2) if lst[i] % 2 != 0]

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(filter_list(nums))

6. 使用单一的列表生成式来产生一个新的列表

  •  要点

列表生成式可以结合条件判断、循环等操作,以简洁的语法生成新列表。列表生成式不仅可以用于生成简单的数值列表,还可以用于处理嵌套列表、字符串列表等。在处理复杂的数据结构时,合理使用列表生成式可以使代码更加简洁易读。

  • 示例

生成一个包含 1 到 10 的平方的列表:

python

squares = [i ** 2 for i in range(1, 11)]
print(squares)

 

7. 用一行代码生成 [1,4,9,16,25,36,49,64,81,100]

python

squares = [x**2 for x in range(1,11)]  # [1,4,9,...,100]
  •  要点

使用列表生成式 [x ** 2 for x in range(1, 11)] 可以在一行代码中完成列表的生成。可以通过修改 range 的参数和表达式,生成不同规律的列表。例如,生成 2 到 20 的偶数的平方列表:[x ** 2 for x in range(2, 21, 2)]

 

8. 输入某年某月某日,判断这一天是这一年的第几天

  •  要点
  1. 先判断该年是否为闰年,闰年 2 月有 29 天,平年 2 月有 28 天。
  2. 然后累加每个月的天数,直到输入的月份,再加上输入的日期。
  3. 可以将该功能封装成一个函数,方便在不同的程序中调用。同时,可以添加输入验证,确保输入的日期是合法的。
  • 示例

python

def day_of_year(year, month, day):
    days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
        days_in_month[1] = 29
    total_days = sum(days_in_month[:month - 1]) + day
    return total_days

year = 2024
month = 3
day = 15
print(day_of_year(year, month, day))

 

9. 两个有序列表l1l2,对这两个列表进行合并不可使用 extend 

  •  要点

使用双指针法,分别遍历两个列表,比较指针所指元素的大小,将较小的元素添加到新列表中,直到其中一个列表遍历完,然后将另一个列表剩余的元素依次添加到新列表中。在处理多个有序列表的合并时,可以使用归并排序的方法,将多个列表两两合并。

  • 示例

python

def merge_lists(l1, l2):
    merged = []
    i, j = 0, 0
    while i < len(l1) and j < len(l2):
        if l1[i] < l2[j]:
            merged.append(l1[i])
            i += 1
        else:
            merged.append(l2[j])
            j += 1
    while i < len(l1):
        merged.append(l1[i])
        i += 1
    while j < len(l2):
        merged.append(l2[j])
        j += 1
    return merged

l1 = [1, 3, 5]
l2 = [2, 4, 6]
print(merge_lists(l1, l2))

10. 给定一个任意长度数组,实现一个函数让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序,如字符串 '123456789',变成 '135798642'

  •  要点
  1. 先将数组中的奇数和偶数分别提取出来。
  2. 对奇数列表进行升序排序,对偶数列表进行降序排序。
  3. 最后将排序后的奇数列表和偶数列表合并。
  4. 可以定义一个函数应用于数据排序和整理的场景中,对于不同的数据类型(如整数列表、字符串列表等),可以进行相应的修改。
  • 示例

python

def sort_array(arr):
    odd_nums = [int(i) for i in arr if int(i) % 2 != 0]
    even_nums = [int(i) for i in arr if int(i) % 2 == 0]
    odd_nums.sort()
    even_nums.sort(reverse=True)
    result = [str(i) for i in odd_nums + even_nums]
    return ''.join(result)

arr = '123456789'
print(sort_array(arr))

相关文章:

  • Javascript网页设计案例:通过PDF.js实现一款PDF阅读器,包括预览、页面旋转、页面切换、放大缩小、黑夜模式等功能
  • 【油猴脚本/Tampermonkey】DeepSeek 服务器繁忙无限重试(20250217优化)
  • 鸿蒙NEXT开发-界面渲染(条件和循环)
  • DeepSeek-R1论文阅读及蒸馏模型部署
  • 华三交换机-链路聚合配置案例
  • Vue2 中使用 UniApp 时,生命周期钩子函数总结
  • 【SpringBoot整合系列】SpringBoot3.x整合Swagger
  • txt文件批量转PDF
  • 为什么要选择3D机器视觉检测
  • Python学习之网络编程
  • PostgreSQL:备库的延迟问题处理步骤
  • 基于LSTM的情感分析
  • 从入门到精通:Postman 实用指南
  • 【玩转全栈】----Django模板语法、请求与响应
  • OpenGL ES -> 投影变换矩阵完美解决绘制GLSurfaceView绘制图形拉伸问题
  • HBase简介
  • 2025年金三银四经典自动化测试面试题
  • [Unity角色控制专题] (借助ai)详细解析官方第三人称控制器
  • UNIX网络编程学习记录2-第一章
  • Centos 7安装docker
  • 涉嫌严重违纪违法,57岁证监会副主席王建军被查
  • 美国第一季度经济环比萎缩0.3%
  • 【社论】法治是对民营经济最好的促进
  • 圆桌|如何应对特朗普政府的关税霸凌?一种联合国视角的思考
  • 黄宾虹诞辰160周年|一次宾翁精品的大集结
  • 坚持科技创新引领,赢得未来发展新优势