python基础知识整理(点滴积累)
最近在做的事情,主要是一些线上的书籍处理过滤、书籍推荐等定时功能,需要用到hive,MR等处理数据,于是轻量级的python脚本成为不二选择,从新手入门,此文作为一个知识的积累,供自己以后查阅 ,也欢迎大家指正。
1.入门简单教程
网上关于python的简明教程还是非常多的,比如简明Python教程。我就是通过这篇文章,粗略的了解了python的解释性、弱语义的特性,也知道了一些常用的数据结构,比如元祖、字典、列表等。此阶段只是简单的了解,可以勉强写程序了,比如最近写的一个用户书籍过滤小程序如下:结构比较混乱,复杂,有待提高。没用到模块化,没用到合适的数据结构,只是实现了功能。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import sys
import re
import copy
import Levenshtein
origin_rela_dict ={} #原创书的关联书籍 {"bookID":[bookID...]}
user_origin_rank ={} #用户原创书rank{userID:{rank:[bookID....]}}
user_origin ={} #用户原创书推荐最后结果 {userID:[bookID...]}
book_arpu ={} #书籍arpu值
publish_category={} #将出版书籍的相关书籍按照标签分类
douban_rela={} #豆瓣相关书籍
composed_rela={} #组合相关书籍
author_rela={} #同作者相关书籍
category_rela={} #同类型热门相关书籍
hot=[] #热门相关
pHot=[] #出版热门20本
boyHot=[] #男频热门20本
girlHot=[] #女频热门20本
boyBook={} #男频所有书籍
girlBook={} #女频所有书籍
pubBook={} #出版所有书籍
boutique_books={} #精品书籍
def generateOrigin(origin_fee_rank,origin_rela,arpu_file,originHot):
fd=open(originHot)
for line in fd:
data=line.strip().split('\t')
bookID,type = data[0],data[1]
#print bookID,type
if type == '男频':
if len(boyHot) <=20:
boyHot.append(bookID)
elif type == '女频':
if len(girlHot) <=20:
girlHot.append(bookID)
fd.close()
# print len(boyHot)
#print len(girlHot)
#导入原创书的关联书籍
fd1 =open(origin_rela)
for line in fd1:
data1 =line.strip().split("\t")
if len(data1)!=3:continue
bookID,origin_rela=data1[1],data1[2].split(",")
if bookID not in origin_rela_dict:
origin_rela_dict.setdefault(bookID,origin_rela)
fd1.close()
#print origin_rela_dict
#减小内存开销处理
fd =open(origin_fee_rank)
#print "chubandsdsd:%d"% len(allpublish)
for line in fd:
rank_tmp={}
user_origin_tmp={}
data=line.strip().split("\t")
if len(data)!=3:continue
userID,compose,type=data[0],data[1],data[2]
tmpDict={}
tmpHot=[]
if type=='男频':
tmpDict =boyBook
tmpHot =boyHot
if type=='女频':
tmpDict =girlBook
tmpHot=girlHot
if type=='其他':
tmpHot=boyHot
book_ranks=compose.strip().split(",")
for book_rank in book_ranks:
book,rank = book_rank.strip().split(":")
rank_tmp.setdefault(book,rank)
for id in rank_tmp:
if id in origin_rela_dict:
count=0
feeRank=int(rank_tmp[id])
origin_rela=origin_rela_dict[id]
for bid in origin_rela:
if bid not in rank_tmp:
count=count+1
rank=count*int(feeRank)
user_origin_tmp.setdefault(rank,[])
user_origin_tmp[rank].append(bid)
iter =sorted(user_origin_tmp.items(),lambda x,y:cmp(x[0],y[0]))
booknum=0
info="%s\t"%userID
flag=False
book_result=[]
for ranks in iter:
arpu_tmp={}
uids=ranks[1] #书籍ID列表
for id in uids:
if id in book_arpu and id not in boutique_books:
arpu_tmp.setdefault(id,book_arpu[id])
iter1 =sorted(arpu_tmp.items(),lambda x,y:cmp(y[1],x[1]))
for it in iter1 :
if it[0] in book_result:continue
book_result.append(it[0])
booknum=booknum+1
if booknum==20:
flag =True
break
if flag:
break
#根据用户的type过滤掉非这个type的书籍
if type =='其他':
if len(book_result)<20:
book_result.extend(tmpHot[:20])
print userID+'\t'+','.join(book_result[:20])
else:
print userID+'\t'+','.join(book_result[:20])
else:
final_book=[]
for bid in book_result:
if bid in tmpDict:
final_book.append(bid)
if len(final_book)<20:
final_book.extend(tmpHot[:20])
print userID+'\t'+','.join(final_book[:20])
else:
print userID+'\t'+','.join(final_book[:20])
if __name__ == "__main__":
type = sys.argv[1]
if type == "1": # 生成原创书推荐 \t 书籍ID
origin_fee_rank,origin_rela,arpu_file,originhot,originfile,boutique= sys.argv[2:]
bookArpuGenerate(arpu_file)
boutiqueGenerate(boutique)
publishGenerate(originfile)
generateOrigin(origin_fee_rank,origin_rela,arpu_file,originhot)
elif type == "2": # 生成出版书籍推荐 \t 相关编号 \t书籍ID
arpufile,allfile,doubanfile,composedfile,authorfile,categoryfile,hotfile,publishfile,boutique= sys.argv[2:]
bookArpuGenerate(arpufile)
boutiqueGenerate(boutique)
listIntialise(doubanfile,composedfile,authorfile,categoryfile,hotfile,allfile)
generatePublish(publishfile)
else: #增量标签处理
tagfile, booktagfile = sys.argv[2:]
IncreTag2Id(tagfile, booktagfile)
其中有一些文件处理的中间函数没有列出来,问题很多,copy运用的不合理,该用set的没有用等等,不过,这也算是一个入门的小程序吧。
2.基础或易忽略的知识点(不断更新)
2.1关于#!/usr/bin/env python
脚本语言的第一行,目的就是指出,你想要你的这个文件中的代码用什么可执行程序去运行它,就这么简单,#!/usr/bin/python是告诉操作 系统执行这个脚本的时候,调用/usr/bin下的python解释器;#!/usr/bin/env python这种用法是为了防止操作系统用户没有将python装在默认 的/usr/bin路径里。当系统看到这一行的时候,首先会到env设置里查找python的安装路径,再调用对应路径下的解释器程序完成操作。
#!/usr/bin/python相当于写死了python路径;#!/usr/bin/env python会去环境设置寻找python目录,推荐这种写法。
2.2关于# -*- coding:utf-8 -*-
默认地,python的.py文件以标准的7位ASCII码存储,然而如果有的时候用户需要在.py文件中包含很多的unicode字符,例如.py文件中需要 包含中文的字符串,这时可以在.py文件的第一行或第二行增加encoding注释来将.py文件指定为unicode格式。关于字符编码的知识,在后面会进 行学习和补充。
2.3关于if __name__ == "__main__":
首先,python文件是以.py来进行结尾的,但是python文件可以作为模块(用于被引用),或者作为主程序(直接执行)来运行,通常模块只 包含函数和变量,用以被调用。而区分模块还是主函数,就是用 if __name__ == "__main__":,__name__就是python脚本的内置属性,用以标记 模块或者主函数。当脚本是直接调用的时候,一般用 python xx.py 运行的时候,就会运行if __name__ == "__main__":后面的程序;而如果是 用 import xx.py引入模块的时候,则不会执行主程序。(说得有点绕,其实很简单)
通常,if __name__ == "__main__":用与模块测试。