学习日志31 python
1 x, y = y, x 是合法的,这是Python的特色语法
x, y = y, x
是 Python 中一种非常简洁且实用的特色语法,用于交换两个变量的值。
这种语法的优势在于:
- 无需额外的临时变量即可完成交换操作
- 代码简洁易读,一眼就能理解其目的
- 执行效率高,在底层会一次性计算右边的值再赋值给左边
例如:
python
运行
a = 10
b = 20# 交换值
a, b = b, aprint(a) # 输出 20
print(b) # 输出 10
这种语法不仅限于两个变量,还可以同时处理多个变量的赋值和交换,如 x, y, z = z, x, y
也是合法的。这体现了 Python 语法的简洁性和灵活性。
2 使用 get(key)
访问不存在的键
题目:
以下程序输出为:
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'北京'}
age = info.get('age')
print(age)
age=info.get('age',18)
print(age)
A None 18
B None None
C 编译错误
D 运行错误正确答案:A
你的答案:C
我的疑惑:
明明就是不存在的键为什么还有输出,我觉得会报错,类似于索引越界?
回答:
在 Python 中,字典的 get()
方法是一种安全获取键值的方式,它与直接使用索引(如 info['age']
)的行为不同:
- 当使用
get(key)
访问不存在的键时,不会报错,而是返回None
- 当使用
get(key, default)
访问不存在的键时,会返回指定的默认值(这里的 18)
在你提供的代码中:
- 第一次
info.get('age')
访问不存在的 'age' 键,返回None
并打印 - 第二次
info.get('age', 18)
同样访问不存在的 'age' 键,但指定了默认值 18,因此返回 18 并打印
所以程序不会出现编译错误或运行错误,而是输出 None
和 18
,正确答案是 A。
这种特性使得 get()
方法在处理可能不存在的键时非常有用,可以避免直接使用索引带来的 KeyError
异常。
3 fromkeys()
在 Python 中,fromkeys()
是字典(dict
)的一个类方法,用于创建一个新字典。
它的主要作用是根据指定的可迭代对象(如列表、元组等)中的元素作为键,并用同一个指定的值来初始化所有键对应的 value。
fromkeys()
的语法格式如下:
python
运行
dict.fromkeys(iterable, value=None)
参数说明:
iterable
:必需参数,是一个可迭代对象,其元素将作为新字典的键。value
:可选参数,用于设置所有键对应的初始值,默认为None
。
示例如下:
python
运行
# 以列表中的元素作为键,默认值为None创建新字典
keys = ['name', 'age', 'gender']
new_dict = dict.fromkeys(keys)
print(new_dict) # 输出: {'name': None, 'age': None, 'gender': None}# 以元组中的元素作为键,指定值为0创建新字典
keys_tuple = ('a', 'b', 'c')
new_dict2 = dict.fromkeys(keys_tuple, 0)
print(new_dict2) # 输出: {'a': 0, 'b': 0, 'c': 0}
需要注意的是,如果 value
是一个可变对象(如列表、字典等),那么所有键都会引用同一个对象,修改其中一个键对应的 value 会影响到其他键。
例如:
python
运行
# 当value是可变对象时的情况
keys = ['a', 'b', 'c']
value = []
new_dict = dict.fromkeys(keys, value)
new_dict['a'].append(1)
print(new_dict) # 输出: {'a': [1], 'b': [1], 'c': [1]}
例题(涉及到)
对列表a = [1,2,3,1,2,4,6]进行去重后,得到列表b,在不考虑列表元素的排列顺序的前提下,下列方法错误的是()A
b = list(set(a))B
b = {}
b = list(b.fromkeys(a))C
a.sort()
b = []
i = 0
while i < len(a):if a[i] not in b:b.append(a[i])else:i += 1D
a.sort()
for i in range(len(a)-1):if a[i] == a[i+1]:a.remove(a[i])else:continue
b = a正确答案:D你的答案:B
我们来分析每个选项的原理和正确性:
选项 A:b = list(set(a))
这是最常见的去重方法,利用集合(set)的特性(元素唯一)先将列表转为集合去重,再转回列表。虽然会改变原顺序,但题目允许不考虑顺序,所以正确。
选项 B:
python
运行
b = {}
b = list(b.fromkeys(a))
这里使用了字典的fromkeys()
方法(如之前讲解的),它会以列表 a 中的元素为键创建字典,而字典的键是唯一的,最后再将字典的键转为列表。这是一种有效的去重方式,结果正确。
选项 C:
python
运行
a.sort()
b = []
i = 0
while i < len(a):if a[i] not in b:b.append(a[i])else:i += 1
先排序使相同元素相邻,再通过循环遍历,只保留第一次出现的元素。逻辑正确,能实现去重。
选项 D 的问题在于:
python
运行
a.sort()
for i in range(len(a)-1):if a[i] == a[i+1]:a.remove(a[i]) # 错误根源else:continue
当使用a.remove(a[i])
删除元素时,列表长度会动态变化,导致后续的索引i
与实际元素不匹配,可能跳过某些元素或重复删除。例如原列表排序后为[1,1,2,2,3,4,6]
,执行时会出现漏删或索引越界问题,最终结果不正确。
因此,错误的方法是选项 D。
4 元组之间是可以进行拼接操作的
题目
在Python3中,以下程序结果为:
one = (1, 2, 3)
two = ('a', 'b')
print(one+two)A None
B 报错
C (1, 2, 3, 'a', 'b')
D [1, 2, 3, 'a', 'b']正确答案:C
你的答案:B
我的误解:元组不是不可变的吗,我所以觉得直接加法会报错?
你的理解存在一个误区:
元组的不可变性是指元组本身的元素不能被修改(无法新增、删除或改变元素),但元组之间是可以进行拼接操作的。
当使用 +
运算符连接两个元组时,并不会修改原来的元组,而是会创建一个新的元组,新元组包含两个原元组的所有元素。
在这个例子中:
python
运行
one = (1, 2, 3)
two = ('a', 'b')
print(one + two)
one + two
会生成一个新的元组 (1, 2, 3, 'a', 'b')
,原元组 one
和 two
本身并没有被改变。因此程序的输出结果是选项 C。
这种特性和字符串类似:字符串也是不可变的,但多个字符串可以通过 +
拼接成一个新字符串。
5 在Python中的三元运算符(也称为条件表达式)写法
题目
下列Python3语句正确的是( )
A min = x if x < y = y
B max = x > y ? x : y
C if (x > y) print(x)
D while True : pass正确答案:D
你的答案:B
A错误:"min = x if x < y = y"语法错误。
Python的三元运算符正确写法应该是"min = x if x < y else y"。
B错误:"max = x > y ? x : y"这是C/Java等语言的三元运算符写法,在Python中不支持这种语法。Python使用"条件表达式"替代,正确写法是"max = x if x > y else y"。
C错误:"if (x > y) print(x)"虽然逻辑正确,但语法错误。Python中if语句后必须使用冒号(:),且下一行代码需要正确缩进。正确写法应为:
if (x > y):
print(x)
所以D选项是唯一符合Python3语法规范的语句。这个知识点考察了Python基本语法规则,包括循环语句、条件语句的写法以及与其他编程语言在语法上的区别。
Python 支持三元运算符(也称为条件表达式),其语法形式为:
python
运行
表达式1 if 条件 else 表达式2
当条件为 True
时,整个表达式的值为 表达式1
;当条件为 False
时,值为 表达式2
。
示例:
python
运行
a = 10
b = 20
max_num = a if a > b else b
print(max_num) # 输出:20
这个例子中,通过三元运算符简洁地实现了取两个数中较大值的逻辑,相当于:
python
运行
if a > b:max_num = a
else:max_num = b
Python 的三元运算符虽然语法形式与其他语言(如 condition ? expr1 : expr2
)不同【不能写成题目里的b选项】,但同样能实现条件判断并返回对应结果的功能。
6 特殊的迭代器(生成器)
题目
在Python3.x环境下,执行以下程序,下列说法中,正确的是( )
s = (i for i in range(1, 3)) # ①
print(s.__next__()) # ②
for i in s:print(i) # ③
A 语句①的s是一个元组
B 语句②的输出结果为1
C 语句③的输出结果为1 2
D 语句③可以替代为
while s.__next__():print(s.__next__())正确答案:B
你的答案:C
让我们分析每个选项:
首先,语句① s = (i for i in range(1, 3))
创建的是一个生成器对象(generator),而不是元组。生成器是一种特殊的迭代器,用于惰性计算。
选项分析:
- A 错误:s 是生成器,不是元组(元组的语法是
(1,2,3)
这种直接包含元素的形式) - B 正确:生成器第一次调用
__next__()
会返回第一个元素 1 - C 错误:语句③会输出 2,因为生成器已经被②消费了第一个元素 1
- D 错误:
while s.__next__():
这种写法不恰当,当生成器迭代完毕后会抛出StopIteration
异常,应该使用try-except
处理或直接使用 for 循环。
选项 D 说 “语句③可以替代为 while s.__next__(): print(s.__next__())
”,这是不正确的,原因有两个:
迭代逻辑错误
生成器的__next__()
方法每次调用都会返回下一个元素。如果写成while s.__next__(): print(s.__next__())
,会导致:- 第一次调用
__next__()
判断条件(比如返回 1) - 第二次调用
__next__()
打印(返回 2) - 第三次调用
__next__()
判断条件时,生成器已无元素,直接抛出StopIteration
异常,程序崩溃
- 第一次调用
缺少异常处理
生成器迭代完毕后,再调用__next__()
一定会抛出StopIteration
异常。而while
循环本身不会处理这种异常,必须手动添加try-except
才能正常运行,比如:python
运行
try:while True:print(s.__next__()) except StopIteration:pass
而原语句③的for
循环会自动处理StopIteration
异常(迭代完毕后会正常退出),因此选项 D 的替代写法是错误的。
执行流程说明:
- 生成器
s
可产生 1 和 2 两个元素 - 语句②调用
__next__()
输出 1,生成器指针移到下一个位置 - 语句③的 for 循环会从当前位置继续迭代,只输出剩下的 2
因此正确答案是 B。