当前位置: 首页 > 后端技术 > Python

那些用起来很酷,但用不好可能会被打的Python操作

时间:2023-03-26 00:40:02 Python

快速将两个有key和value的列表合并成字典>>>a=["key1","key2","key3"]>>>b=["value1","value2","value3"]>>>dict(zip(a,b)){'key1':'value1','key2':'value2','key3':'value3'}这个操作的目的对于爬虫工程师来说很常见,例如:你需要收集一些键值对类型的信息,然后你可能会遇到一些平台接口返回这些信息,直接以列表的形式返回只有值,键是硬编码在代码或请求参数中的。这时候就可以利用这个操作快速将它们合并成一个字典,这样就可以方便的检索Value,value部分的可读性会好很多。另一种情况是,你可能会在某些网站上遇到这种键值对信息。HTML中的key和value元素是水平关系,key和value没有可区分的标识。在这些情况下,我们只能通过提取整个键值对部分的元素并转化为列表,然后根据列表的下标区间切片分别提取key和value的列表,然后进行合并他们入字典。例如:>>>result=["key1","value1","key2","value2","key3","value3"]>>>result[0::2]['key1','key2'','key3']>>>结果[1::2]['value1','value2','value3']>>>dict(zip(结果[0::2],结果[1::2])){'key1':'value1','key2':'value2','key3':'value3'}需要注意的是,当key和value个数不一致时,这个操作会被自动忽略对于列表末尾部分的值,需要保证key和value是正确的。简单来说,如果你的键列表比值列表多了一个值,那么最终的字典将缺少键列表中最后一个额外的值。将元素按照头、尾、中部分进行快速切割,分别赋值给三个变量>>>a="123456789"#也可以是这样的列表>>>a1,*a2,a3=a>>>a1'1'>>>a2['2','3','4','5','6','7','8']>>>a3'9'这个操作的目的对于爬虫工程师或者一些会接触到私有协议的后端工程师来说应该是比较常见的。比如:你可能会遇到一些基于TCP或者UDP的私有协议,那么他们可能会定义一个内容类型头,通信内容组成的结构,校验码等东西,每次通信都会返回给你这样一个东西,然后您需要剪切它们并将它们分配给不同的变量。这时候,就可以使用这个操作来快速实现Thisworked。当然,这个操作不能乱用。你最好能够保证它的内容不会改变。在私有协议的情况下,可以通过判断协议版本号来保证其内容一定是这个结构。快速解压一个包含嵌套列表的列表,同时将嵌套列表中的值赋给不同的变量>>>result=[1,2,[3,4],5]>>>[a,b,[c,d],e]=result>>>a1>>>b2>>>c3>>>d4>>>e5这个操作在处理一些私有协议的时候偶尔也会用到,可以用这个操作非常方便,可以将列表中的值快速赋值给不同的变量进行处理。如果您只需要嵌套列表中的第一个值而不需要其余值怎么办?可以这样:>>>result=[1,2,[3,4,5]]>>>[a,b,[c,*_]]=result>>>a1>>>b2>>>总之,c3和前面的操作一样,用星号处理后面的多个值,赋值给下划线等临时变量丢弃。注:下划线变量的用途和含义可自行通过搜索引擎搜索。网上很多文章都提到了,这里就不赘述了。遍历不同长度的嵌套列表时,按照头部和尾部进行切割,分别赋值给两个变量>>>result=[["items","item1","item2","item3"],["status",1]]>>>forkey,*valuesinresult:...print(key)...print(values)...>>>items['item1','item2','item3']>>>status[1]这个操作在处理一些私有协议或者奇怪的平台接口的时候偶尔会用到,也就是对方返回给你的内容可能是这样一个嵌套的列表,第一个值sublist是key,后面的部分是value,有些奇葩的平台甚至sublists的顺序可能都不一样。这时候如果用这个操作来获取key和value,就方便多了。你不需要关心它有多少个值,也不需要按下标0来获取嵌套列表中的key。你只需要Justdothisfor然后处理键和值就大功告成了。>>>{key:valuesforkey,*valuesinresult}{'items':['item1','item2','item3'],'status':[1]}你甚至可以把这段代码直接把它们写在一行中,直接转换成字典进行后续处理。快速解压一个字典,把里面的key和value赋给不同的变量>>>a={"key1":"value1","key2":"value2","key3":"value3"}>>>(key1,value1),(key2,value2),(key3,value3)=a.items()>>>key1'key1'>>>value1'value1'>>>key2'key2'>>>目的value2'value2'操作对于爬虫工程师和后端工程师来说也是很常见的。比如:你需要提取一个接口返回的带有状态码、状态信息和数据的内容,你需要判断状态码是否代表请求成功?这时候如果用key逐个取值赋值会很麻烦,但是如果用这个操作就可以很快解决。可能光这么说还不够直观,我们来看一个示例代码:>>>result={"code":200,"data":{"balabala":111},"msg":None}>>>(_,code),(_,data),(_,msg)=result.items()>>>code200>>>data{'balabala':111}>>>msg>>>当然这个操作不能乱用,使用这个操作的时候,需要保证字典中key的顺序严格一致,否则可能会提取出错误的内容,所以为了防止提取前顺序乱了,可以先key排序,保证顺序严格一致。那么字典的内容是否会发生变化也是需要考虑的。如果你写的代码需要很严谨,那你就老老实实的一个一个按键吧。毕竟,如果在中间位置多了一把钥匙,拿到它,事情就完全不一样了。动态创建函数有时候你可能会遇到这样一种特殊情况:你有一些不同的值需要用同一个函数来处理,但是由于限制,你不能将这个函数泛化为一个并传递参数。唯一的处理方法就是写多个不同名字的函数分别处理。或者您可能只是需要动态创建一个临时函数来使用。这时候如果使用这个操作,就可以轻松解决这个问题。你只需要像这样动态创建一个函数:>>>fromtypesimportFunctionType>>>>>>func=FunctionType(compile(...("deffunc():\n"..."print(1)\n"..."return2"),..."",..."exec"...).co_consts[0],globals())>>>print(func())12注意:括号内的字符串会被自动拼接,这是Python中多行字符串的一种写法。好处是字符串内容不会像三引号一样受到缩进的影响。如果想了解更多,可以自行查看Python官方文档。里面的弦乐部分讲的就是这个小技巧。我们也可以动态生成里面的函数代码字符串(比如使用format)来修改函数名称和内容,甚至可以使用像Jinja这样的模板渲染库来实现更方便的函数代码生成。由于DjangoAdmin的action函数的参数是固定的,如果需要给action函数传递参数,需要通过中间页实现,而我又不想获取中间页,还有几个不同的参数需要分别处理,所以就用动态创建函数的方法来解决。动态导入有时你可能有一些扩展代码需要在运行时动态导入。这时候就可以使用这个操作了。比如我们需要导入算子库:>>>importimportlib>>>>>>module=importlib.import_module("operator")那么这个模块变量就是导入模块的名字,我们可以直接使用为正常导入时,比如我们要调用它的add函数:>>>module.add(1,1)#加法运算符2的动态调用有时需要在动态导入后进行动态调用。这时候你可以这样做:>>>importimportlib>>>>>>module=importlib.import_module("operator")>>>func=getattr(module,"add")>>>func(1,1)2当然,在使用动态创建、动态导入、动态调用这些比较hacky的操作时,一定要注意安全问题,即如果使用时有些参数需要用户输入,一定要勾选输入内容,避免被用来直接执行危险代码。比如你提供一个动态创建函数的功能,如果你不检查内容,一些坏人可能会直接通过os库调用命令行来黑你的机器,这是非常危险的。那么以上就是本次分享的全部内容。这些骚操作其实还有很多。有兴趣的话平时可以多关注一下别人写的代码和各种论坛。有时候会有一些意想不到的收获。以上就是本次分享的全部内容。想了解更多python知识,请前往公众号:Python编程学习圈,发“J”免费领取,每日干货分享