[Python] seek使用 bytes转int 浮点特定位数

最近用python写了个计算pcm平均RMS幅度(dBfs)的脚本,其中不少小细节在此列一下

1、python没有跟C一样拿到参数个数的argc,需要使用len(sys.argv)拿到
2、seek第一个参数为offset,第二个为偏移位置 0-file start, 1-current,2-file end
3、python一个除“/”结果为浮点,即使可以整除,“//”为取整
4、‘rb’读文件拿到的数据为bytes类型,如果要转成int需要int.from_bytes方法,可以设置大小端跟有无符合。
5、浮点特定位数打印 print(“%.2f”% num);

if len(sys.argv) != 2: #there is no ARGC
print(“param must be 2”)
exit(0)

with open(sys.argv[1], ‘rb’) as fd:
    cnt = fd.seek(0,2)#2-seek to the end
    cnt = cnt//2 #use // here, other wise cnt is a float
fd.seek(0,0) #0-seek to start
for i in range(cnt):
num = fd.read(2)
        num=int.from_bytes(num, byteorder=”little”, signed=”True”)# byte to int
total += (num*num)
dbfs=20*math.log10(math.sqrt(total/cnt)/32768)+3.013
print(“%.2f”% dbfs); #to keep 2 decimal points

[PYTHON]python中的关键字参数

在部分函数中,我们会看到传入的参数带有关键字,这类参数称为关键字参数(keyword arguments)。
比如:
headers={….}
r=requests.get(URL,headers=headers)
这种传入参数的方法看起来更简洁清晰。
在python函数定义的时候,可以使用*在强制使用关键字参数。如下示例:
def addd(a, *,b,c):
    print(a,b,c)
#addd(1,2,3)#error
#addd(1,b=2,3)#error
addd(1,b=2,c=3)

def adda(*,a,b,c):
    print(a,b,c)
#adda(a=1,2,3)#error
#adda(a=1,2,3)#error
adda(a=1,b=23,c=2)
需要注意的是,所有在*之后的参数都会被视为关键字参数。

如果函数参数中有可变参数,则可变参数(变量名前紧跟*)之后的所有参数都被视为关键字参数。可变参数本身不是关键字参数。如下*arg:

def addb(a, *arg,b,c):
    print(a, arg,b,c)
#addb(10,(1,2),20,30)#error
addb(10,(1,2),b=20,c=30)
addb(10,2,b=20,c=30)

[PYTHON]Ubuntu1604安装python3.6

Ubuntu 1604默认python3的版本为3.5, 并不能直接通过输入apt-get install的命令来安装python3.6,因为python3.6并不在ubuntu 1604的官方源里,所以需要手动添加,然后再安装。(1610版本之后应该不需要)

命令如下:
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.6

安装库:
可以使用如下命令安装库
python3.6 -m pip install

 

[PYTHON] apache2 CGI运行python脚本

ubuntu 1604 apache2默认并未开启CGI python支持,需要进行手动配置。

首先编辑/etc/apache2/apache2.conf,增加以下配置:
<Directory /var/www/html/>
Options +ExecCGI
PassEnv LANG
AddHandler cgi-script .py
</Directory>

AddHandler python-program .py

配置完成之后运行service apache2 restart重启服务。

测试:
在/var/www/html新建python文件

#!/usr/bin/python
print “Content-type: text/html\n”
print “Hello, world!”

保存之后更改文件权限,加入可执行权限。
此时,可以通过浏览器运行相应的文件。如果运行显示的是内容,而不是运行结果,原因可能是没有load cgi模块,则需要运行sudo a2enmod cgi,然后重启apache服务即可。若想要获取url传入参数,可以使用cgi库

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import cgi
print(“Content-Type: text/html\n”)
print(“Hello, world!”)
arguments = cgi.FieldStorage()
for i in arguments.keys():
    print(i)
    print(arguments[i].value)

运行结果如下:

[PYTHON]split 与 re.split

Python中,split作为字符串的方法之一,可以进行字符串的简单分割。
如:
>>> s=’hello world’
>>> s.split()#不带参数表示默认使用空格分割
[‘hello’, ‘world’]

分割后的字符串变为list类型。

但是如果涉及到稍微复杂点的分割,如下:
s=”HELLO <a href=’LOL’> World”要输出 HELLO WORLD,则用split无法完成,此时需要re.split,使用正则表达式来完成。此例中,需要将”<“之后,”>”之前的字符作为分割符,来进行分割。示例如下:

>>> re.split(‘<.*>?’,s)# .*表示中间匹配任意字符,除了换行。 ?表示非贪婪(non-greedy)模式, 即只取到第一个完全匹配的字符
[‘HELLO ‘, ‘ World’]

若s如下:
s=”HELLO <a href=’LOL’>HAHA> World”
>>> re.split(‘<.*?>’,s)#非贪婪模式,只到第一个”>”
[‘HELLO ‘, ‘HAHA> World’]
>>> re.split(‘<.*>’,s)#贪婪模式,到最后一个”>”
[‘HELLO ‘, ‘ World’]

 

 

 

 

[PYTHON]map filter reduce 使用简介

Map, filter,reduce 都是针对可迭代类型(iterable)的循环操作,返回想要的结果。三者使用上有相似性,功能不太相同。

三个函数都需要两个参数,第一个参数是函数名,是指要针对每个元素做的操作,第二个参数为可迭代的序列。

先来看一个例子,假设一个list mylist=[1,2,3,4,5],我们要把每个元素分别乘2输出,正常方法如下:

mylist=[1,2,3,4,5]
result=[]
i=0
while i < len(mylist):
    result.append(mylist[i]*2)
    i+=1
print(result)

我们使用循环完成了上述功能,但是为了使代码简洁,我们可以通过使用map,而不是用循环。我们只需使用3行代码就可以完成上述功能。

mylist=[1,2,3,4,5]
out=list(map(lambda x:x*2, mylist))
print(out)

所以,map完成的是将mylist中每个元素分别带入lambda函数中进行计算,最终仍然返回list类型的结果,即[2, 4, 6, 8, 10]

类似,filter也是依次将每个元素带入进行计算,只不过filter返回的是运行结果为真的元素。假设我们想要打印出list中小于4的元素,可以使用如下代码。最终只打印出了1,2,3

mylist=[1,2,3,4,5]
out=list(filter(lambda x: x<4, mylist))
print(out)

[1, 2, 3]

Reduce也是类似,只不过reduce返回的不是元素,而是累计计算各个元素的运行结果。

假设我们要计算list中各个元素的和,可以使用以下代码:最终打印15

mylist=[1,2,3,4,5]
out=reduce(lambda x,y : x+y, mylist)
print(out)

[PYTHON]如果函数中的默认参数为list…

Python定义函数的时候,可以设定参数的默认值,如果调用时没有相应传入参数,python会将默认值带入到函数内部。

>> def test(a, b=2):
… print(a)
… print(b)

>>> test(10,20)
10
20
>>> test(10)  #此例中,只传入一个参数,b默认为2
10
2

但是,如果默认参数为list,可能有时候表现的结果可能会出乎意料。看一下下面的例子,最终的结果会是什么。

def ListExtend(value, list=[]):
    list.append(value)
    return list

list1=ListExtend(4)
list2=ListExtend(‘abc’,[])
list3=ListExtend(‘m’)

print(list1)
print(list2)
print(list3)

 

运行结果:
[4, ‘m’]
[‘abc’]
[4, ‘m’]

你可能会想,list1不是应该是[4],list3不是应该是[‘m’]吗?难道不是每次调用默认参数list都应该重新初始化?
不是的。这涉及到python中针对函数默认参数的处理。当第一次不带参数调用ListExtend时候,python已经创建了一个新的list,当再次调用的时候,python不会重新创建list,而是继续使用之前创建的。因此,每一次不带参数调用都会在此list基础上进行append。

[PYTHON]python中比较两个list的区别与共同项

在Python中,查找两个list中共同项,或者区别项,可以通过set(集合)来完成。
set中包含现成的比较方法.difference与.intersection

假设两个list为list1,list2,先将两个list转为set:
s_list1=set(list1)
s_list2=set(list2)
s_list1.difference(s_list2)表示返回list1中与list2不同的item的list
s_list1.intersection(s_list2)表示返回list1与list2中相同的item的list

以下程序为例:

list1=[‘apple’, ‘banana’,’peach’,’watermelon’]
list2=[‘strawberry’, ‘watermelon’]

s_list1=set(list1)
s_list2=set(list2)
print(“s_list1=”, end=”)
print(s_list1)
print(“s_list2=”, end=”)
print(s_list2)

print(“Items in s_list1 DIFFERENT from items in s_list2 are:”)
out = s_list1.difference(s_list2)
print(out)
print(“Items in s_list2 DIFFERENT from items in s_list1 are:”)
out = s_list2.difference(s_list1)
print(out)

print(“Items in s_list1 SAME with items in s_list1 are:”)
out = s_list1.intersection(s_list2)
print(out)

—————————————–结果为—————–

s_list1={‘apple’, ‘banana’, ‘peach’, ‘watermelon’}
s_list2={‘watermelon’, ‘strawberry’}
Items in s_list1 DIFFERENT from items in s_list2 are:
{‘apple’, ‘banana’, ‘peach’}
Items in s_list2 DIFFERENT from items in s_list1 are:
{‘strawberry’}
Items in s_list1 SAME with items in s_list1 are:
{‘watermelon’}

[PYTHON]Python3中str的join与split操作

join, split为python3中针对文本处理较为常见的方法
Join 合并多个可迭代类型转换为string,比如将list转换为string
split为将string转换为list,可以传入分割符,默认为空格,
也可以传入最大需要分割的数量,超过这个数量之后将不再分割

str1="hello,this is a test"
>>> str1.split(' ', maxsplit=2) #使用空格分隔,最多分隔两次
['hello,this', 'is', 'a test']
>>> str1.split()
['hello,this', 'is', 'a', 'test']
>>> c=str1.split()
>>> ' '.join(c)  #使用空格将list连接成string
'hello,this is a test'

[PYTHON]Python中的函数可变参数


首先看一个示例

def testfunc(*a, **b):

这可不是类似C语言传入指针的函数,这是python中可变参数的表示,

*a表示可变参数,传入的类型为tuple

**b传入的类型为dict

>>> def testfunc(a, *b):

…     print(a)

…     print(b)

>>> testfunc(10, 15, 22, 40,100)

10

(15, 22, 40, 100)

可以看出,a只接收一个参数,剩下的均为b接收,如果我们打印出type(b)的话,会发现b为tuple类型。

**表示可变参数作为一个dict类型传入,既然是dict类型,调用就需要遵循特定的规则。

>>> def testfunc(a, **b):

…     print(a)

…     print(b)

>>> testfunc(10,c=100,d=150)

10

{‘d’: 150, ‘c’: 100}

 

需要注意的是:

  • 一个函数内不能同时出现两个tuple可变参数或者同时出现两个dict可变参数,如下列代码会报错:

 def test(**a, **b): 或者  def test(*a, *b):

  • 一个函数内可以同时存在一个tuple可变参数和一个dict可变参数,但是tuple可变参数在函数定义时必须在前面如
    def test(*a, **b):
    反之如果这样定义def test(**a, *b):则会出错。