python技巧

以下是我从网上和书上找到的有用并且也是pythonic的技巧,其中大部分都已经用在自己代码里了。大部分都是对于python 2.7,而对于python 3的以后也会另外整理一份。


  • 用位运算判断奇偶性:

def is_even(x):

    return False if x & 1 else True


  • 循环时, 使用 while 1 while True 更快!

  • 文件相关操作:

os.chdir(path)    改变当前工作目录 

os.path.dirname(path) #返回文件路径

os.path.abspath(path) #返回绝对路径

os.path.isdir(dir)    #判断是否是个文件夹 

os.path.isfile(file)    #判断是否是文件 


  • 处理命令行输入

option_parser = OptionParser() 

option_parser.add_option(“-d”, “—date”, dest=“date”, help=“input date”) 

option_parser.add_option(“-r”, “—rb”, dest=“rb_num”, help=“rb number”) 

(options, args) = option_parser.parse_args() 

print options.date, options.rb_num 


  • 读取配置文件:

parser = ConfigParser.ConfigParser() 

parser.read('./conf.ini') 

host, port, user, passwd = [x[1] for x in parser.items(dbname)] 


  • 子进程调用方法: 

proc = subprocess.Popen(find_cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)    #后面两个pipe不要忘加 

cout, cerf = proc.communicate()    #进程结束才会返回 

return_code = proc.poll()    #获取进程返回码 


  • sys.modules是一个全局字典,该字典是Python启动后就加载在内存中。每当程序员导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。

  • log的使用:

import logging

logger = logging.getLogger(__name__)

logger.addHandler(handler)

logger.setLevel(logging.DEBUG)

#通过logging.basicConfig对日志的输出格式及方式做修改, 如:

logging.basicConfig(level=logging.DEBUG,

     format='',

     datefmt='%a, %d %b %Y %H:%M:%S',

     filename='mylog.log'

)

console = logging.StreamHandler()

#设置日志级别

console.setLevel(logging.info)

formatter = logging.Formatter()

comsole.setFormatter(formatter)

logging.getLogger().addHandler(console)

logging.debug('This is a debug message')

logging.info('this is a info message')


  • urllib2的使用:

import urllib2

url = '' 

user_agent = 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/48.0.2564.23 Mobile Safari/537.36' 

req = urllib2.Request(url)     

req.add_header('User-Agent', user_agent)    #添加报头 

response = urllib2.urlopen(req) 

page = response.read() 

print response.geturl()    #如果有重定向,获得最终url 


  • 使用代理编写爬虫:

1. 参数是一个字典{'类型':'代理ip:端口'}

proxy_support = urllib2.ProxyHandler({})

2. opener = urllib2.build_opener(proxy_support)

3. opener.open(url)

网页状态码,301永久重定向,302临时重定向,404网页不存在,403网页禁止访问

import cookielib

cookie = cookielib.CookieJar()

opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))

response = opener.open(url)

某些站点有所谓的反盗链设置,其实就是检查你发送请求的header里面,referer站点是不是他自己, 所以我们只需要像把headersreferer改成该网站即可


  • with的魔力

with语句需要支持上下文管理协议的对象, 上下文管理协议包含__enter____exit__两个方法. with语句建立运行时上下文需要通过这两个方法执行进入和退出操作.

property与装饰器结合实现属性私有化(更简单安全的实现getset方法)

class Student(object):    #object as the parent class 

    def __init__(self): 

        self._score = 0 

     

    @property 

    def score(self):    #getter 

        return self._score 



    @score.setter 

    def score(self, value):    #setter 

        #some check 

        self._score = value 


  • 神奇partial

from functools import partial 

def sum(a, b): 

    return a + b 


def test(): 

    func = partial(sum, 2)    #sum的第一个参数绑定为

    print func(3)    #sum的第二个参数为


  • pythonunicode和中文转换,这个很容易搞错

python2: str->byte: encode 

               byte->str: decode 

python2中的str其实是byte,所以要用decode方法打印出真正的内容 

在代码文件的开头要定义encode的方式:# -*- coding: utf-8 -*- 


  • import技巧:

__import__动态加载模块,比如事先不知道模块的名字,或者加载配置文件中字符形式的模块 

__import__ (name[, globals[, locals[, fromlist[, level]]]])

name (required): 被加载 module 的名称

globals (optional): 包含全局变量的字典,该选项很少使用,采用默认值 global()

locals (optional): 包含局部变量的字典,内部标准实现未用到该变量,采用默认值 local()

fromlist (Optional): 被导入的 submodule 名称

level (Optional): 导入路径选项,默认为 -1,表示同时支持 absolute import relative import


  • 计算向量的余弦相似度: 

Module1 = np.linalg.norm(a) 

Module2 = np.linalg.norm(b) 

inner_prod = np.dot(a, b) 

Cos_sim = inner_prod / (module1 * module2) 


  • 使用默认字典

# 好处是放入新的key时不用判断是否已存在,直接用d[key].append(val)即可

d = collections.defaultdict(lambda:[])


  • namedtuple

cards = collections.namedtuple('cards', ['color', 'suit'])


  • zip的妙用

# 每三个生成一个tuple

l = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8]

zip(*[iter(l)] *3)


  • pow(x, y, z)  #(x^y) mod z

  • 使用itertools.chain()将二维列表打散成一维的

>>> from itertools import *

>>> l = [[1, 2], [3, 4]]

>>> list(chain(*l))

[1, 2, 3, 4]


  • Finding the most frequent element in a list, x:

max(set(x), key=x.count)


  • 一句话生成n-gram

ngrams = zip(*[words[i:] for i in range(n)])


  • A fast way to compute large fibonacci numbers using generators:

     def fibonacci_generator():

1. a,b = 0,1

2. while True:

3.     yield a

4.     a,b = b, a+b

f = fibonacci_generator()

fib_nums = [f.next() for i in xrange(300)


from operator import itemgetter

metro_data = [

... ('Tokyo' , 'JP', 36.933, ( 35.689722 , 139.691667 )),

... ('Delhi NCR' , 'IN', 21.935, ( 28.613889 , 77.208889 )),

... ('Mexico City' , 'MX', 20.142, ( 19.433333 , - 99.133333 )),

... ('New York-Newark' , 'US', 20.104, ( 40.808611 , - 74.020386 )),

... ('Sao Paulo' , 'BR', 19.649, ( -23.547778, -46.635833)),

... ]

# 对字典排序,当然也可以用lambda

sorted(metro_data, key=itemgetter(0)) #按照第一个字段进行排序,即城市名


例如:按照字典的value进行排序

sorted(dict.items(), key=itemgetter(1), reverse=True)


cc_name = itemgetter(1, 0)

for city in metro_data:

     print cc_name(city)


  • 阶乘计算方法:

def fact(n):

     return reduce(lambda a,b: a*b, range(1, n+1))


y = np.empty((10, 1))

y.fill(value)         #申请一个10*1的向量,值填充为value


  • python 获取当前时间 time.strftime( ISOTIMEFORMAT, time.localtime() )
  • 计算时间差,其中入参为seconds

date1 = time.strptime(time.ctime(float(c[3])))

date1 = datetime.datetime(date1[0],date1[1],date1[2],date1[3],date1[4],date1[5])

date2 = time.strptime(time.ctime(float(a[6])))

date2 = datetime.datetime(date2[0],date2[1],date2[2],date2[3],date2[4],date2[5])

print (date2-date1).seconds


  • 检查一个文件夹是否存在,如果不存在就创建它:

if not os.path.exists(directory):

     os.makedirs(directory)


  • from subprocess import check_output   # 父进程等待子进程完成
  • np.array_equal(a, b) #判断两个数组大小和元素是否相等

import seaborn as sns     #seaborn也是数据可视化工具包,接受dataframe格式的数据

tips = sns.load_dataset("tip")

g = sns.FacetGrid(tips, col="time")

The main approach for visualizing data on this grid is with the FacetGrid.map() method. Provide it with a plotting function and the name(s) of variable(s) in the dataframe to plot

g.map(plt.hist, "tip")

  • docopt根据你写的文档描述,可以自动为你生成解析器,可以非常容易的为你的python程序创建命令行界面(Command Line InterfaceCLI)。
  • the operator == compares the values of objects, while is compares their identities

The presence of references is what keeps an object alive in memory. When the reference count of an object reaches zero, the garbage collector disposes of it.

repr()

Return a string representing the object as the developer wants to see it.

str()

Return a string representing the object as the user wants to see it.


  • 可利用python进行传输

python -m SimpleHTTPServer 80


  • 将秒数转化成可读的时间格式

datetime.datetime.fromtimestamp(1458369661).strftime("%Y-%m-%d”)


  • 合并list:

a = [[1, 2], [3, 4], [5, 6], [7, 8]]

b = sum(a, [])

# b = [1, 2, 3, 4, 5, 6, 7, 8]


  • if判断时尽量避免直接和TrueFalse比较, 如:

if int_value:    #判断是否为0

    print int_vaue

但,当需要和None比较时,使用is判断

if input is None:

    print “Empty value”


  • 避免在if语句中重复写变量

if name == ‘Tom’ or name == ‘Peter’ => if name in (‘Tom’, ‘Peter’)


  • enumerate可以生成下标:

for index, element in enumerate(list):

    print index, element


  • for…else…中的else用于for循环中没有一个元素满足条件的操作,如:

for user in get_all_users():

    for email_address in user.get_email_address():

        if is_malformed(email_address):

            print “has a malformed mail”

            break

    else:

        print “All mails are valid”


  • 函数的默认参数不要用[],最好使用None

def func(mylist=[]) => def func(mylist=None)


  • python3中可以使用*捕获list剩余的元素: first, second, third, * = my_list[0:10]
  • 最好为字典的get操作提供一个默认值,如:

lov_severity = config.get(’severity’, ’Info’)


  • 字典推导式:

user_email = {user: get_mail(user) for user in phonebook if has_mail(user)}

result_list = ['True', 'False', 'File not found']

result_string = ''.join(result_list)

  • 定义一个class时候,最好定义__str__()方法,打印关于这个classreadable信息

  • 使用_代替不需要的变量,

(name, age, _, _) = get_user_info(user)


  • main函数最后加上sys.exit,如果有错则返回错误代码,否则就返回0sys.exit(0)

  • 如果想要import多个包,可以放在圆括号中,如

from foo import (bar, bad, qux, quux)


  • 推荐的模块导入顺序:

1. 标准库的模块

2. 安装在sitepackages中的第三方库

3. 当前项目中已有的模块


  • 叉乘的写法:sum(map(operator.mul, vec1, vec2))

accumulate([1,2,3,4,5]) --> 1 3 6 10 15

chain('ABC', 'DEF') --> A B C D E F    #用于打散多维list

compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F    

dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1    #从第一个不满足条件的元素开始,遍历之后的所有元素

filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8    #过滤不满足条件的元素

starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000

takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4    #选择满足条件的元素


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值