Python重温笔记番外篇

news2024/11/27 3:53:21

1. 写在前面

今天这篇文章是python重温笔记的番外,整理一些面试中的问题以及遇到过的一些坑, 正好借着这个机会把前面的知识进行一个串联, 要不然这些知识很容易就会遗忘, 毕竟知识多而又不太容易常用到。 涉及到的知识包括列表推导式, 高阶函数的使用, 字典排序, 字符串, 日期, 文件遍历, 生成器, 正则, 线程等, 所以还是比较全面的, 以后如果再遇到python方面的练习题的话, 也可以再进行相应的补充。

2. python基础篇

2.1 一行代码生成奇数列表

一行代码生成[1, 2, 5, 7, 9, 11, 13, 15, 17, 19], 这个考察的是列表推导式, 比较简单

[i for i in range(1, 20) if i % 2 !=0]   # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

2.2 等差数列

产生一个首项为 10,公差为 12,末项不大于 100 的列表, 这个是列表生成式

# 写一个等差数列
list(range(10, 100, 12))   #     [10, 22, 34, 46, 58, 70, 82, 94]

2.3 一行代码求1到10000内整数和

考察了高阶函数reduce的使用

# 一行代码求1到10000内整数和
sum(range(1, 10000))

from functools import reduce
reduce(lambda x, y: x+y, range(10000))  #     49995000

2.4 打乱一个列表

使用 random 模块,shuffle 函数打乱原来列表,值得注意是 in-place 打乱。

# 打乱一个列表
import random
a = list(range(10))
random.shuffle(a)
a   #   [2, 4, 5, 7, 9, 8, 0, 3, 6, 1]

2.5 字典按照value排序返回新字典

考察的字典的排序, sortedkey方法

# 字典按照value排序并且返回新字典
d = {'a':12, 'b':50, 'c':1, 'd':20}

dict(sorted(d.items(), key=lambda x: x[1]))   #{'c': 1, 'a': 12, 'd': 20, 'b': 50}

2.6 删除list的重复元素, 保证顺序不变

如果只是删除重复元素,直接使用内置 set 函数,去重,但是不能保证原来元素顺序。

# 如何删除list里面重复元素, 并且保证顺序不变
b = []
a = [3, 2, 2, 2, 1, 3]
for i in a:
    if i not in b:
        b.append(i)
b   #     [3, 2, 1]

2.7 找出两个列表中的相同和不同元素

这个考察的是集合的交, 并运算, 给定列表 a = [3,2,2,2,1,3],列表 b = [1,4,3,4,5],使用集合,找出相同元素:

# 怎么找到两个列表的相同元素和不同元素
a = [3, 2, 2, 2, 1, 3]
b = [1, 4, 3, 4, 5]

# 集合的交
def ana(a, b):
    aset, bset = set(a), set(b)
    same = aset.intersection(bset)
    differ = aset.difference(bset).union(bset.difference(aset))
    return same, differ
ana(a, b)  #     ({1, 3}, {2, 4, 5})

2.8 把字符串处理成字典

输入串 "k0:10|k1:2|k2:11|k3:5",输出字典 {k0:10,k1:2,...}

  • 第一层 split,根据分隔符 |,分割出 k0:10,k1:2,k2:11,k3:5
  • 第二层 split,根据分隔符 :,分割出新字典的键值对

这个可以使用map函数。

# 字符串处理成字典   
s = "k0:10|k1:2|k2:11|k3:5"
d = {mi[0]:mi[1] for mi in map(lambda x: x.split(':'), s.split('|'))}
d  #   {'k0': '10', 'k1': '2', 'k2': '11', 'k3': '5'}

2.9 输入日期, 判断是一年的第几天

这个考察datetime模块, 使用 datetime 模块,提取日期 date 对象,调用 timetuple() 方法,返回一个 struct_time 对象,属性 tm_yday 便是这一年的第几天:

# 输入日期, 判断这一天是这一年的第几天
from datetime import datetime

def get_day_of_year(y, m, d):
    return datetime(y, m, d).date().timetuple().tm_yday

get_day_of_year(2020, 2, 1)     #     32

2.10 遍历目录和子目录, 抓取某个特定后缀名的文件

os 模块walk 方法实现递归遍历所有文件,os.path.splitext 返回文件的名字和扩展名,如果扩展名匹配到 ext,则添加到 res 中。

# 遍历目录与子目录, 抓取.py文件
import os

def get_files(directory, ext):
    res = []
    for root, dirs, files in os.walk(directory):
        print(root, dirs, files)   # root是遍历目录的当前路径, dirs是该路径下的目录, files是该路径下的文件
        for filename in files:
            name, suf = os.path.splitext(filename)
            if suf == ext:
                res.append(os.path.join(root, filename))  
    return res

## 上面函数的执行过程就是从传入的目录开始, 得到传入的目录, 该目录下的子目录和该目录下的文件, 对于该目录下文件再次进行遍历, 查找相应后缀名
## 的目录, 然后再遍历传入目录的子目录, 依然是上面的那种套路进行查找
get_files('E:/Jupyter Notebook/Python全栈60天', '.png')

结果如下:

E:/Jupyter Notebook/Python全栈60天 ['.ipynb_checkpoints', 'img', 'Python60天专栏录制短动画'] ['Day1-Day2.ipynb', 'Day10_python文件操作案例.ipynb', 'Day11_python时间模块的使用总结.ipynb', 'Day17_Python列表生成式高效使用的案例.ipynb', 'Day18_Python对象间的相等性比较等使用总结.ipynb', 'Day19_yield关键字和生成器, nonlocal关键字和global关键字总结.ipynb', 'Day20_Python函数的5类参数.ipynb', 'Day21_迭代器和生成器.ipynb', 'Day22_多线程和协程.ipynb', 'Day24—Python.ipynb', 'Day3-Day4.ipynb', 'Day5-Day6.ipynb', 'Day7-Day8.ipynb', 'Day9_字符串操作与正则.ipynb', 'Day_23_python的Collections.ipynb', 'test.py']
E:/Jupyter Notebook/Python全栈60天\.ipynb_checkpoints [] ['Day1-Day2-checkpoint.ipynb', 'Day10_python文件操作案例-checkpoint.ipynb', 'Day11_python时间模块的使用总结-checkpoint.ipynb', 'Day17_Python列表生成式高效使用的案例-checkpoint.ipynb', 'Day18_Python对象间的相等性比较等使用总结-checkpoint.ipynb', 'Day19_yield关键字和生成器, nonlocal关键字和global关键字总结-checkpoint.ipynb', 'Day20_Python函数的5类参数-checkpoint.ipynb', 'Day21_迭代器和生成器-checkpoint.ipynb', 'Day22_多线程和协程-checkpoint.ipynb', 'Day24—Python-checkpoint.ipynb', 'Day3-Day4-checkpoint.ipynb', 'Day5-Day6-checkpoint.ipynb', 'Day7-Day8-checkpoint.ipynb', 'Day9_字符串操作与正则-checkpoint.ipynb', 'Day_23_python的Collections-checkpoint.ipynb']
E:/Jupyter Notebook/Python全栈60天\img ['.ipynb_checkpoints', '1_2', '3_4', '4_5', '9_10'] ['1.png']
E:/Jupyter Notebook/Python全栈60天\img\.ipynb_checkpoints [] []
E:/Jupyter Notebook/Python全栈60天\img\1_2 [] ['1.gif', '1.png', '2.png', '3.gif', '3.png', '4.png', '5.png', '6.png', '7.png']
E:/Jupyter Notebook/Python全栈60天\img\3_4 [] ['1.gif', '1.png', '10png.png', '11.png', '12.png', '2.png', '3.png', '4.png', '5.png', '6.png', '7.png', '8png.png', '9.png']
E:/Jupyter Notebook/Python全栈60天\img\4_5 [] ['1.png']
E:/Jupyter Notebook/Python全栈60天\img\9_10 [] ['1.png', '2.png', '3.png', '4.png', '5.png', '6.png']
E:/Jupyter Notebook/Python全栈60天\Python60天专栏录制短动画 [] ['Day19-2.mp4', 'Day19-3.mp4', 'Day19.mp4', 'Day2.mp4', 'Day21-2.mp4', 'Day21.mp4', 'Day4.mp4', 'Day6.mp4', 'Day7.mp4']


['E:/Jupyter Notebook/Python全栈60天\\img\\1.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\1.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\2.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\3.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\4.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\5.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\6.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\1_2\\7.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\3_4\\1.png',
 'E:/Jupyter Notebook/Python全栈60天\\img\\3_4\\10png.png']

3. Pyhon 进阶篇

3.1 单机4G内存, 处理10G文件的方法

# 单机4G内存, 处理10G文件的方法
def python_read(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f:
            yield line

# pandas的read_csv, 这个方法更加的灵活
def pandas_read(filename, sep=',', chunksize=5):
    reader = pd.read_csv(filename, sep=sep, chunksize=chunksize)
    while True:
        try:
            yield reader.get_chunk()
        except StopIteration:
            print('---Done---')
            break

3.2 统计一个文本单词频次最高的10个单词

使用 yield 解耦数据读取 python_read 和数据处理 process

  • python_read:逐行读入
  • process:正则替换掉空字符,并使用空格,分隔字符串,保存到 defaultdict 对象中。
# 统计一个文本单词频次最高的10个单词
def python_read(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f:
            yield line

d = defaultdict(int)

def process(line):
    for word in re.sub('\W', " ", line).split():
        d[word] += 1

# 使用两个函数,最后,使用 Counter 类统计出频次最高的 10 个单词:
for line in python_read('write_file.py'):
    process(line)

most10 = Counter(d).most_common(10)
print(most10)

3.3 反转一个整数

这个得考虑的全面一些。 主要逻辑如下:

  • 如果 x 位于 (-10,10) 间,直接返回;
  • 然后,将 x 转换为字符串对象 sx;
  • 如果 x 是负数,截取 sx[1:],并反转字符串;
  • 如果 x 是正数,直接反转字符串;
  • 最后使用内置函数 int() 转化为整数。
# 反转一个整数  
def reverse_str(sx):
    return sx[::-1]

def reverse_int(x:int):
    # 如果在-10-10之间, 直接返回
    if -10 < x < 10:
        return x
    
    sx = str(x)
    
    # 如果x是负数, 那么就反转后面的
    if sx[0] == '-':
        sx = reverse_str(sx[1:])
        x = int(sx)
        return -x
    
    sx = reverse_str(sx)
    return int(sx)

reverse_int(-1)   # -1
    

3.4 判断输出结果

# 看下面函数的执行结果
def f():
    i = 0
    def foo(x):
        return i*x
    rtn = []
    while i < 3:
        rtn.append(foo)   # rtn 添加三个函数 foo,但是并未发生调用。
        i += 1
    return rtn

for fs in f():
    print(fs(10))
    
# 直到执行 fs(10) 时,内嵌函数 foo 才被调用,但是此时的 enclosing 变量 i 取值为 3:
30
30
30

这个要注意, 内嵌函数 foo 使用的两个变量 i 和 x,其中 x 为其形参,i 为 enclosing 域内定义的变量。rtn 添加三个函数 foo,但是并未发生调用。

3.5 判断函数的形参调用

已知 filename 为 ‘.’,c 为 10,正确为 foo 函数传参的方法,以下哪些是对的,哪些是错误的?

# 如下函数foo的调用哪些是正确的?
def foo(filename, a=0, b=1, c=2):
    print('filename: %s \n c:%d' %(filename, c))

foo('.', 10)     # 错误,a 被赋值为 10
filename: . 
 c:2
foo('.', 0, 1, 10) # 正确,c 是位置参数
filename: . 
 c:10
foo('.', 0, 1, c=10) # 正确,c 是关键字参数
filename: . 
 c:10
foo('.', a=0, 1, 10)  # 错误,位置参数不能位于关键字参数后面
  File "<ipython-input-5-c704ccbf612c>", line 1
    foo('.', a=0, 1, 10)
                 ^
SyntaxError: positional argument follows keyword argument
foo(filename='.', c=10)   # 正确,filename 和 c 都是关键字参数
foo('.', c=10)    # 正确,filename 位置参数,c 是关键字参数
filename: . 
 c:10
filename: . 
 c:10

3.6 lambda函数的形参和返回值

key值为lambda函数, 说说lambda函数的形参和返回值

def longer(*s):
    return max(*s, key=lambda x: len(x))
longer({1, 2, 5, 7}, {1, 5, 7}, {2, 4, 6, 7, 8})   #     {2, 4, 6, 7, 8}
  • lambda 函数的形参:s 解包后的元素值,可能取值为:{1,3,5,7}、{1,5,7}、{2,4,6,7,8} 三种。
  • lambda 函数的返回值为:元素的长度,可能取值为:{1,3,5,7}、{1,5,7}、{2,4,6,7,8} 的长度 4,3,5。

3.7 正则匹配负整数

匹配所有负整数, 不包括0. 正则表达式: ^-[1-9]\d*$

  • ^-表示字符串以-开头
  • [1-9]表示数字1到9, 注意不要写成\d, 因为负整数没有-0开头的
  • \d*表示数字0到9出现0次, 1次或者多次
  • $ 表示字符串以数字截尾

在这里插入图片描述

import re
s = ['-1', '-15768', '9', '-01', '10', '-']
pat = r'^-[1-9]\d*$'
rec = re.compile(pat)
rs = [i for i in s if rec.match(i)]
rs  #   ['-1', '-15768']

3.8 正则匹配负浮点数

正确写出匹配负浮点数的正则表达式,要先思考分析。

考虑到两个实例:-0.12、-111.234,就必须要分为两种情况。

  • 适应实例-0.12的正则表达式, ^-0.\d*[1-9]\d*$, 注意要考虑到 -0.0000 这种非浮点数,因此正则表达式必须这样写。不要想当然的写^-0.\d*$, ^-0.\d*[1-9]*$, 或者^-0.\d*[0-9]$, 因为这几个都会匹配-0.
  • 适应实例-111.234的正则, ^-[1-9]\d*.\d*$

使用|, 综合两种情况即可: ^-0.\d*[1-9]\d*$|^-[1-9]\d*.\d*$
在这里插入图片描述

import re
s = ['-1', '-1.5756', '-0.00', '-000.1', '-1000.10']
pat = r'^-0.\d*[1-9]\d*|^-[1-9]\d*.\d*$'
rec = re.compile(pat)
rs = [i for i in s if rec.match(i)]
rs   #    ['-1.5756', '-1000.10']

3.9 使用filter()求出列表中大于10的元素

filter 函数使用 lambda 函数,找出满足大于 10 的元素。

a = [15, 2, 7, 20, 400, 10, 9, -15, 107]
list(np.array(a)[np.array(a)>10])

list(filter(lambda x: x>10, a))   #  [15, 20, 400, 107]

3.10 说说下面map函数的输出结果

m = map(lambda x, y: min(x, y), [5, 1, 3, 4], [3, 4, 3, 2, 1])
list(m)  # [3, 1, 3, 2]

# map 函数当含有多个列表时,返回长度为最短列表的长度;

3.11 说说reduce函数的输出结果

from functools import reduce
reduce(lambda x, y: x*y+1, [1, 2, 3, 4, 5])  # 206

3.12 x=(i for i in range(5)), x是什么类型?

x是生成器类型, 与for等迭代

x = (i for i in range(5))
next(iter(x))   # 0

3.13 可变类型和不可变类型分别列举三个:

  • 可变类型: 列表, 字典, 集合, deque
  • 不可变类型: 字符串, 整型, 浮点, 元组等

只有不可变类型才能作为字典等的键

3.14 is 和==有什么区别?

  • is: 用来判断两个对象的标识号是否相等
  • ==: 用来判断值或者内容是否相等, 默认是基于两个对象的标识号比较

也就是说,如果 a is b 为 True 且如果按照默认行为,意味着 a==b 也为 True。

3.15 写一个学生类Student

添加一个属性id, 并实现id相等, 则认为是同一位学生的功能

class Student:
    def __init__(self, id, name):
        self.id = id
        self.name = name
    def __eq__(self, student):
        return self.id == student.id
s1 = Student(10, 'xiaoming')
s2 = Student(20, 'xiaohong')
s3 = Student(10, 'xiaoming2')

s1==s2  # False
s1==s3 # True

3.16 有什么方法获取类的所有属性和方法?

获取下面类 Student 的所有属性和方法,使用 dir() 内置函数。

class Student:
    def __init__(self,id,name):
        self.id = id
        self.name = name
    def __eq__(self,student):
        return self.id == student.id
dir(Student)
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']
dir(s1)
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'id',
 'name']

3.17 python如何动态或者和设置对象的属性

class Student:
    def __init__(self,id,name):
        self.id = id
        self.name = name
    def __eq__(self,student):
        return self.id == student.id
# Python 使用 hasattr 方法,判断实例是否有属性 x:
hasattr(s1, 'id')
hasattr(s1, 'address')

#使用 setattr 动态添加对象的属性,函数原型:
if not hasattr(s1, 'address'):
    setattr(s1, 'address', 'beijing')
    print(hasattr(s1, 'address'))  #  True
dir(s1)
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'address',
 'id',
 'name']
s4 = Student(12, 'wu')
dir(s4)
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'address',
 'id',
 'name']

3.18 实现一个按照2* i+1自增的迭代器

实现类AutoIncrease, 继承于Iterator对象, 然后从写两个方法:

  • iter
  • next
from collections.abc import Iterator

class AutoIncrease(Iterator):
    def __init__(self, init, n):
        self.init = init
        self.n = n
        self.__cal = 0
    
    def __iter__(self):
        return self
    def __next__(self):
        if self.__cal == 0:
            self.__cal += 1
            return self.init
        while self.__cal < self.n:
            self.init *= 2
            self.init += 1
            self.__cal += 1
            return self.init
        raise StopIteration
iter = AutoIncrease(1, 10)
for i in iter:
    print(i)
1
3
7
15
31
63
127
255
511
1023

3.19 实现文件按行读取和操作数据分离

使用 yield 解耦按行读取和操作数据的两步操作:

def read_line(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f:
            yield line

def process_line(line: str):
    pass

for line in read_line('.'):
    process_line(line)

3.20 使用python锁避免脏数据出现的例子

使用多线程编程,会出现同时修改一个全局变量的情况,创建一把锁 locka:

import threading
import time

locka = threading.Lock()
a = 0
def add1():
    global a
    try: 
        locka.acquire()   # 获得锁
        tmp = a + 1
        time.sleep(0.2)   #  模拟IO操作
        a = tmp
    finally:
        locka.release()   # 释放锁

threads = [threading.Thread(name='t%d'%(i,),target=add1) for i in range(10)]
[t.start() for t in threads]

# 多线程的代码,由于避免脏数据的出现,基本退化为单线程代码,执行效率被拖累。

3.21 说说死锁, GIL锁和协程

多个子线程在系统资源竞争时,都在等待对方解除占用状态。

比如,线程 A 等待着线程 B 释放锁 b,同时,线程 B 等待着线程 A 释放锁 a。在这种局面下,线程 A 和线程 B 都相互等待着,无法执行下去,这就是死锁。

为了避免死锁发生,Cython 使用 GIL 锁,确保同一时刻只有一个线程在执行,所以其实是伪多线程。

所以,Python 里常常使用协程技术来代替多线程。多进程、多线程的切换是由系统决定,而协程由我们自己决定。协程无需使用锁,也就不会发生死锁。同时,利用协程的协作特点,高效的完成了原编程模型只能通过多个线程才能完成的任务。

4. python中容易忽略的坑点整理

这个模块整理下之前在python里面遇到的一些容易出错且忽略的一些点:

  1. 删除列表元素
    这个是一个比较简单的问题, 可以越简单,我们往往就会越忽略一些东西, 删除列表元素, 就是给定一个列表, 要求删除指定元素, 比如[1,3,5,3,2], 要求删除里面的3, 我们可能会写出这样的代码:

    def del_item(lst,e):
        for item in lst:
            #print(item)
            if item == e:
                lst.remove(item)
        return lst
    

    我们的思路就是遍历一遍列表, 如果元素等于指定的元素, 我们就执行删除(注如果单纯的用remove或者pop只会删除某一个元素), 这样的思路确实是没有问题, 但是内部真的是按照我们想的执行吗? 其实不是的, 边遍历边删除是一个危险的思想, 这时候每删除一个元素, 移掉位置 i 后的所有元素索引都要减一, 这时候其实就会跳过一些元素没有被检查, 可以打印一下item试试。 正确的做法:找到被删除元素后,删除,同时下次遍历索引不加一;若未找到,遍历索引加一

    def del_item2(lst,e):
        i = 0
        while i < len(lst):
            if lst[i] == e:
                lst.remove(lst[i])
            else:
                i += 1
        return lst
    

    当然, 也有一个简单的方式, 如果会filter这个函数的话, 一行代码就可以搞定:

    list(filter(lambda x: x!=e, lst))
    
  2. 函数默认参数为空
    Python 函数的参数可设为默认值。如果一个默认参数类型为 list,默认值为设置为 []。这时候会有问题吗? 比如下面这个例子:

    def delta_val(val, volume=[]):
        if volume is None:
            volume = []
        size = len(volume)
        for i in range(size):
            volume[i] = i + val
        return volume
    

    面试的时候经常会问到的一个题目, 有问题吗? 肯定是有的, 我们可以进行一个测试:

    lst1 = delta_val(10)
    lst1   # []    这是个空
    
    lst1.append(1)
    lst1.append(2)   
    lst1   # [1, 2] 
    
    #  貌似没有发现任何问题, 可是我们再重新建立一个新的列表
    lst2 = delta_val(10)
    lst2   # [10, 11]  会发现lst2的初始值直接变成了[10, 11]  而我们想要的是[], 所以问题出现在了这里
    

    原来调用函数 delta_val 时,默认参数 volume 取值为默认值时,并且 volume 作为函数的返回值。再在函数外面做一些操作,再次按照默认值调用,并返回。整个过程,默认参数volume 的 id 始终未变。

  3. 解包
    Python 中,支持多值赋值给多变量的操作。最常见的用法,一行代码交换两个变量:

    In [34]: a, b = 1, 2
    In [35]: a, b = b, a
    

    但是,面对稍微复杂点的类似操作,如果不搞懂多值赋值的执行顺序,就会掉入陷阱。如下例子,如果心算出的结果等于 a = 3, b = 5,那么就说明没弄明白执行顺序。

    In [38]: a, b = 1, 2
    In [39]: a, b = b+1, a+b
    

    记住一点:多值赋值是先计算出等号右侧的所有变量值后,再赋值给等号左侧变量。所以,答案应该是:a = 3, b = 3

    这种多值赋值,是一种解包(unpack)操作。

    既然是解包,那么就得先有打包。的确,等号右侧的多个变量,会被打包(pack)为一个可迭代对象。

    赋值操作,就相当于解包。这种解包操作,有时非常有用。比如,foo 函数返回一个 list,如下:

    def foo():
        result = [1,'xiaoming','address','telephone',['','','...']]
        return result 
    

    但是,我们只需要列表中的前两项。更为简洁、紧凑的做法:等号左侧定义两个我们想要的变量,其他不想要的项放到 others 变量中,并在前加一个 *,如下所示:

    sid, name, *others = foo()
    
    In [64]: sid
    Out[64]: 1
    
    In [65]: name
    Out[65]: 'xiaoming'
    

    *others 会被单独解析为一个 list:

    In [66]: others
    Out[66]: ['address', 'telephone', ['', '', '...']]
    

目前先整理这么多,python语言也是博大精深,后面遇到新内容会随时补充。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1357336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单片机快速入门

参考连接&#xff1a; 安装MinGW-64&#xff08;在win10上搭建C/C开发环境&#xff09;https://zhuanlan.zhihu.com/p/85429160MinGW-64; 链接&#xff1a;https://pan.baidu.com/s/1oE1FmjyK7aJPnDC8vASmCg?pwdy1mz 提取码&#xff1a;y1mz --来自百度网盘超级会员V7的分享C…

Python打印Python环境、PyTorch和CUDA版本、GPU数量名称等信息

代码&#xff1a; import torch import platformgpu_num torch.cuda.device_count() torch_version torch.__version__ python_version platform.python_version()print("Python Version: Python %s" % python_version) print("PyTorch Version: %s" %…

[Javaweb/LayUI/上机考试作业/开源]学生/图书/课程/仓库等管理系统六合一基础功能通用模板

展示 考试要求 给定用户表和六张图书/教师/顾客/仓库....的表&#xff08;随机给每人抽选&#xff09;&#xff0c;要求实现用户登录注册&#xff0c;异步更新&#xff0c;对物品增删改查&#xff0c;精确/模糊查询等。 环境 tomcat 9 mysql 8 java 17 项目结构 项目类图 写前…

分布式【zookeeper面试题23连问】

1. ZooKeeper是什么&#xff1f; ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;它是集群的管理者&#xff0c;监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终&#x…

Prometheus二进制安装包部署

Prometheus安装部署 一&#xff0c;下载安装包并解压 **下载地址&#xff1a;**https://github.com/prometheus/prometheus/releases 因为服务器上下载速度太慢&#xff0c;所以可以提前在物理机上下载上传到服务器&#xff0c;本次安装使用的版本为&#xff1a;prometheus-…

深度神经网络中的混合精度训练

Mixed-Precision Training of Deep Neural Networks | NVIDIA Technical Blog 目录 混合精度成功训练的技术 FP32 累加 损失缩放 loss scaling FP32 Master Copy of Weights 混合精度训练迭代过程 AMP混合精度训练介绍 FP16和FP32的区别 FP16的优势 FP16的问题 解决P…

shell sshpass 主机交互 在另外一台主机上执行某个命令 批量管理主机 以及一些案例

目录 作用安装 sshpasssshpass 用法在远程主机执行某个命令 案例批量传输密匙批量拷贝文件批量修改密码 作用 就是用一台主机 控制另外一台主机免交互任务管理工具方便批量管理主机使用方法就是在ssh 前边加一个 sshpass 安装 sshpass # 安装 sshpass yum -y install sshpas…

MongoDB快速实战与基本原理

MongoDB 介绍 什么是 MongoDB MongoDB 是一个文档数据库&#xff08;以 JSON 为数据模型&#xff09;&#xff0c;由 C 语言编写&#xff0c;旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。文档来自于“JSON Document”&#xff0c;并非我们一般理解的 PDF、WORD 文档…

【K8S 云原生】Pod资源限制、Pod容器健康检查(探针)

目录 一、docker的重启方式和K8S重启方式 1、Pod的重启方式&#xff1a; 2、docker的重启策略&#xff1a; 二、yaml文件快速生成&#xff1a; 三、pod的状态&#xff1a; 四、Pod的资源限制 1、限制的方式和种类 2、CPU的限制的格式&#xff1a; 五、K8S拉取镜像的策…

电源板设计方案怎么写 (评审文件)

1. 首先是大致的图形模块化说明。 1. 大致的框图 2. 统计项目需要的功率和需求 此表格数据是假的&#xff0c;只是为了展示 电源种类是&#xff1a; 板子需要供电需要的电压和对应电压最大的电流。 电源时序是&#xff1a; 板子…

智能穿戴时代 | 米客方德SD NAND的崭新优势

SD NAND在智能穿戴上的优势 SD NAND是一种可以直接焊接在智能穿戴设备主板上的存储芯片&#xff0c;其小型化设计有助于紧凑设备尺寸&#xff0c;同时提供可靠的嵌入式存储解决方案。 这种集成设计减少了空间占用&#xff0c;同时确保设备在高度活动的环境中更为稳定。SD NAND…

【C#】知识点实践序列之UrlEncode在线URL网址编码、解码

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是2024年第8篇文章&#xff0c;此篇文章是C#知识点实践序列文章&#xff0c; 博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 地址编码大家应该比较经常遇到和使用到&…

rk3566 armbian修复usb2.0并挂载U盘

文章目录 usb接口修复一 执行命令二 修改rk3566-panther-x2.dts⽂件三 查看是否识别 U盘格式化、挂载一 U盘格式化1.1 查看U盘1.2 查看U盘文件系统类型1.3 格式化为ext4系统 二 挂载U盘2.1 手动挂载2.2 自动挂载&#xff08;可选&#xff09; usb接口修复 一 执行命令 将位于…

【数据库系统概论】数据库恢复机制

系统文章目录 数据库的四个基本概念&#xff1a;数据、数据库、数据库管理系统和数据库系统 数据库系统的三级模式和二级映射 数据库系统外部的体系结构 数据模型 关系数据库中的关系操作 SQL是什么&#xff1f;它有什么特点&#xff1f; 数据定义之基本表的定义/创建、修改和…

泽攸科技完全自主研制的电子束光刻机取得阶段性成果

国产电子束光刻机实现自主可控&#xff0c;是实现我国集成电路产业链自主可控的重要一环。近日&#xff0c;泽攸科技联合松山湖材料实验室开展的全自主电子束光刻机整机的开发与产业化项目取得重大进展&#xff0c;成功研制出电子束光刻系统&#xff0c;实现了电子束光刻机整机…

FreeRTOS——互斥信号量知识总结及其实战

1互斥信号量的概念 1&#xff09;互斥信号量&#xff1a;是一个拥有优先级继承的二值信号量&#xff0c;在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中&#xff01; 2&#xff09;优先级继承&#xff1a;当一个互斥信号量正在被一个低优先级的…

MySQL 8.0 开关 Redo Logging

一 前言 前几天有客户测试使用云数据库的时候提出 要禁止mydumper 关闭redo log的操作 (说白了就是导入数据时保持MySQL 实例的redo logging功能)&#xff0c; 这才想起 在 MySQL 8.0.21 版本中&#xff0c;开启了一个新特性 “Redo Logging 动态开关”。 在新实例导数据的场…

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式-CSDN博客 1、 Hadoop 是什么 &#xff08;1&#xff09;Hadoop是一个由Apache基…

第二百四十六回

我们在上一章回中介绍了"修改页面导航中遇到的问题"沉浸式状态样相关的内容&#xff0c;本章回中将介绍如何修改Avatar的大小.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在正常使用CirCleAvatar组件时可以通过该组件的radius属性来修改它的…

ssm基于web的素材网的设计与实现+vue论文

基于web的素材网站的设计与实现 摘要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。传统的素材信息管理模式&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以人力为主的管理…