python 基础

# 计算 2 的 3 次方
print(2 ** 3)

# 取 1 到 100 的和
print(sum(range(1, 101)))

# 写一个函数找出一个整数数组中,第二大的数
def second_largest(arr):
    if len(arr) < 2:
        return None
    first, second = float('-inf'), float('-inf')    # 初始化为负无穷大
    for num in arr:
        # 如果当前数大于最大值
        if num > first:
            first, second = num, first
        # 如果当前数在最大值和第二大值之间
        elif first > num > second:
            second = num
    return second

# 元组 t1 中只有一个元素怎么表示
t1 = (1,)           # 不加逗号 会输出 <class 'int'>
print(type(t1))     # 输出 <class 'tuple'>,表示 t1 是一个元组

# 元组 t2 进行+=后输出的结果
t2 = (1, 2, [30, 40])
t2 += [50, 60]       # typeError: can only concatenate tuple (not "list") to tuple
print(t2)            # 输出 (1, 2, [30, 40],

# +和 += 的区别
# + 会创建一个新的元组,而 += 会修改原有的元组
# 两边必须是同类型的对象才能相加,+= 右操作数往往可以是任何可迭代对象。
l = list(range(6))
l += 'qwerty'
print(l)    # 输出 [0, 1, 2, 3, 4, 5, 'q', 'w', 'e', 'r', 't', 'y']

# 字符串 s1 反转顺序
s1 = 'aStr'
print(s1[::-1])

# 字符串 s2 转换为首字母大写
s2 = 'i love python'
print(s2.title())

# 交换 s1和 s2 的值
s1, s2 = s2, s1
print(s1, s2)  # 输出 'i love python' 'aStr'

# 字符串 s3 中查找子串 Love 的位置
s3 = 'I Love Python'
print(s3.find('Love'))

# 字符串 s4 中替换 o 为 ee
s4 = 'I Love Python'
print(s4.replace('o', 'ee'))

# 字符串 s5 拆分成列表
s5 = 'I Love Python'
print(s5.split())

# all([]) 和 any([]) 分别输出什么
print(all([]))  # 输出 True,因为空列表被认为是所有元素都满足条件
print(any([]))  # 输出 False,因为空列表没有任何元素满足条件

# 列表 l1 中找到最大值和最小值
l1 = (123, 888, 666)
print(max(l1))
print(min(l1))

# 列表 l2 转字符串
l2 = ['Python', 'Circle', 'is', 'ok']
print(' '.join(l2))

# 列表 l3 按 age 由大到小排序
l3 = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
def sort_by_age(l3):
    return sorted(test_list,key=lambda x:x['age'],reverse=True)

# 列表 l4 中 ok 出现了几次
l4 = ['i', 'am', 'ok', 'ok', 'ok', 'ok']
print(l4.count('ok'))

# 列表 l4 去重
new_l4 = list(set(l4))  # 使用 set 去重,返回一个新的列表
print(l4)
print(new_l4)

# 列表 l5 前中后加入元素变成 1 2 three 4 5, 再让 l5 变回原样
l5 = [1, 2, 4]
l5.append(5)
l5.insert(2, 'three')
print(l5)
l5.pop()
l5.remove('three')    # remove 只删除第一次出现的,出现多次删不干净
print(l5)

# 列表 l6 反转元素
l6 = [1, 2, 3, 4, 5]
l6.reverse()
print(l6)
l6[::-1]    # 另一种反转方式
print(l6)

# 列表 l5 l6 找出他们相同的元素和不同的元素,以及数量
set1 = set(l5)  # 先转集合
set2 = set(l6)
print(set1 & set2)          # 找出相同的元素
print(len(set1 & set2))     # 找出相同的元素的数量
print(set1 ^ set2)          # 找出不同的元素
print(len(set1 ^ set2))     # 找出不同的元素的数量

# 列表 l7 中取超过长度的索引
l7 = ['a','b','c','d','e']
print(l7[10:])   # 切片操作不会抛出 IndexError 错误,返回一个空列表。

# 列表 l8 用 *= 后会不会产生新的列表
l8 = [1, 2, 3]
print(id(l8))  # 输出 l8 的内存地址
l8 *= 2
print(l8)  # 输出 [1, 2, 3, 1, 2, 3], *= 操作会修改原列表,而不是创建一个新的列表
print(id(l8))

# 创建字典的方法
dict_a = dict(one=1, two=2, three=3)
dict_b = {'one': 1, 'two': 2, 'three': 3}
dict_c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
dict_d = dict([('two', 2), ('one', 1), ('three', 3)])
dict_e = dict({'one': 1, 'two': 2, 'three': 3})
print(dict_a, dict_b, dict_c, dict_d, dict_e)

# 把列表转为字典
dial_code = [
 (86, 'China'),
 (91, 'India'),
 (1, 'US'),
 (55, 'Brazil'),
 (7, 'Russia'),
 (81, 'Japan')
]
coutry_code = {coutry:code for code, coutry in dial_code}
print(coutry_code)

# 字典 d1 按value值进行排序
d1 = {'a':24,'g':52,'i':12,'k':33}
print(sorted(d1.items(), key=lambda x: x[1]))   # x[0]代表用key进行排序;x[1]代表用value进行排序。

# 字典 d2 中取一个不存在的 key
d2 = {'a': 1, 'b': 2, 'c': 3}
d2.get('aa', 'default_value')  # 使用 get 方法可以避免 KeyError,如果 key 不存在则返回默认值

# 字典 d2 为这个不存在的 key 赋值不用 if 判断
d2.setdefault('aa', []).append(4)  # 使用 setdefault 方法可以为不存在的 key 设置默认值,并返回该 key 的值

# 字典 d3 中的类型
d3 = {}
print(type(d3))  # 输出 <class 'dict'>,表示 d3 是一个字典

# 闭包的后期绑定问题
def multi():
    return [lambda x : i*x for i in range(4)]
print([m(3) for m in multi()])  # 输出结果是[9,9,9,9] 不是[0,3,6,9]产生的原因是Python的闭包的后期绑定导致的,这意味着在闭包中的变量是在内部函数被调用的时候被查找的,因为,最后函数被调用的时候,for循环已经完成, i 的值最后是3,因此每一个返回值的i都是3,所以最后的结果是[9,9,9,9]

# 判断输出
b = 3
def fun(a):
    print(a)
    print(b)
    b = 7
fun(5)  # 报错 "UnboundLocalError" Python编译函数的定义体时,先做了⼀个判断,那就是 b 是局部变量,因为在函数中给它赋值了。但是执⾏ print(b) 时,往上⼜找不到 b 的局部值。

# 如何判断对象类型
print(isinstance('aa', str))

# 判断输出
aa = 10
cc = [aa]
aa = 15
print(cc)
# 1. 不可变类型(如整数、字符串)的变量重新赋值时,会创建新的内存空间,原引用不会被修改。
# 2. 列表等容器存储的是元素的引用,而非值本身,因此不会随变量后续的重新赋值而改变。

# 判断输出
x = (i for i in range(10))
print(type(x))  # 输出 <class 'generator'>,因为 x 是一个生成器表达式

# 判断输出
def append_element(lst):
    lst.append(100)

my_list = [1, 2, 3]
append_element(my_list)
print(my_list) # 输出:[1, 2, 3, 100] 可变对象

# 判断输出
def change_str(s):
    s = s + " world"

text = "hello"
change_str(text)
print(text)  # 输出:hello

# 判断输出 元组是可变的吗?
m = [1, 2]
n = [3, 4]
t = (m, n)
m.append(5)
n.append(6)
print(t)    # ([1, 2, 5], [3, 4, 6])