- #空白形式
- i = 1 + \
- 2 #反斜线代表一个语句在下一行续写
- # print (i)
- #模块
- import re
- my_regex = re.compile("[0-9]+",re.I)
- # print (my_regex)
- import re as regex #别名
- my_regex = regex.compile("[0-9]+",regex.I)
- # print(my_regex)
- from collections import defaultdict, Counter #使用模块中的特定值,显示导入,直接使用,不必提前获取权限
- lookup = defaultdict(int)
- my_counter = Counter()
- match = 10 #如果是破坏者,可以将模块的全部内容导入命名空间,这也许会不加提示地覆盖原先定义的变量
- from re import * #re有一个match函数
- # print(match) #<function match at 0x0000000002985D08>
- #算法
- a = 5 / 2 #结果为float
- a = 5 // 2 #整除
- # print (a)
- #函数
- def double(x):
- return x*2
- # print (double(3))
- def apply_to_one(f):
- return f(1)
- my_double = double #指向之前的函数
- x = apply_to_one(my_double) #python函数是第一类函数,第一类函数意味着可以将他们赋给其他变量,也可以像其他参数一样传递给函数
- # print(x) #等于2
- y = apply_to_one(lambda x:x+4) #也很容易生成简短的匿名函数,或者lambda lambda 是为了减少单行函数的定义而存在的。
- # print(y) #等于5
- another_double = lambda x:2*x #可以将lambda赋给变量,不建议这么做
- # print (another_double(2))
- def another_double(x): return 2*x #建议使用def
- # print(another_double(2))
- def my_print(message = "my default message"): #默认参数可以赋值给函数参数,当你需要默认值以外的值时需要具体说明
- print(message)
- # my_print("hello") #输出hello
- # my_print() #输出my default message
- def subtract(a = 0, b = 0): #有时候通过名字指定参数会有用
- return a - b
- # print(subtract(10, 5)) #打印5
- # print(subtract(0, 5)) #打印-5
- # print(subtract(b = 5)) #打印-5
- #字符串
- single_quoted_string = 'data science'
- double_quoted_string = "data science" #两个等价
- tab_string = "\t" #表示tab字符
- # print (len(tab_string)) # 1
- not_tab_string = r"\t" #表示字符'\'和't' 使用r""生成一个原始的字符串
- # print (len(not_tab_string)) # 2
- multi_line_string = """this is the first line.
- and this is the second line
- and this is the third line""" #通过三重[两重]引号生成多行的字符串
- # print(multi_line_string)
- #异常
- try:
- print(0/0)
- except ZeroDivisionError:
- print("cannot divide by zero")
- #集合
- integer_list = [1, 2, 3]
- heterogeneous_list = ["string", 0.1, True]
- list_of_lists = [integer_list, heterogeneous_list, []]
- # print(len(integer_list))
- # print(sum(integer_list)) #列表是一个有序集合,和其他语言中数组概念类似,但增加了函数功能
- x = range(10) #是列表[0, 1, 2, ..., 9]
- zreo = x[0] # 0
- one = x[1] # 1
- nine = x[-1] # 9 ,最后一个元素的python惯用法
- eight = x[-2] # 8 ,倒数第二个元素的python惯用法
- # x[0] = -1 # 'range' object does not support item assignment
- # print(x)
- first_three = x[:3] #[0,1,2]
- three_to_end = x[3:] #[3,4,...,9]
- one_to_four = x[1:5] #[1,2,3,4]
- last_three = x[-3:] #[7,8,9]
- without_first_and_last = x[1:-1] #[1,2,3,...,8]
- copy_of_x = x[:] #[0,1,2,3,...,9]
- # print(copy_of_x)
- # print(1 in [1,2,3]) #True python可以通过操作符in确认列表成员
- # print(0 in [1,2,3]) #False 确认每次回遍历列表元素,除非列表很小,否则不应该进行确认,除非不在乎需要花费多长时间
- x = [1,2,3]
- x.extend([5,6,7]) #串联列表
- # print(x)
- y = x + [4,5,6]
- # print(y)
- x.append(0) #一次在原列表上只增加一项
- # print(x)
- x,y = [1,3] #如果知道列表中元素的个数,可以方便地从中提取值,现在x是1,y是3,如果等式两端元素个数不同,会报出提示valueError
- _,y = [1,3] #如果希望忽略某些值,常见的选择是使用下划线
- # print(y) #现在y == 3 不用关心第一个元素是什么
- #元组
- my_list = [1,2] #元组是列表的亲表哥。你对列表做的很多操作都可以对元组做,但不包括修改。元组通过圆括号(或者什么都不加)而不是方括号来给出具体的描述
- my_tuple = (1,2)
- other_tuple = 3,4
- my_list[1] = 3
- # print(my_list) #my_list现在是[1,3]
- try:
- my_tuple[1] = 3
- except TypeError:
- print("cannot modify a tuple")
- def sum_and_product(x,y): #元组是通过函数返回多重值的便捷方法
- return (x+y), (x*y)
- sp = sum_and_product(2,3)
- s,p = sum_and_product(5,10)
- # print(p)
- x,y = 1,2
- x,y = y,x #元组和列表都可以进行多重赋值,python风格的互换变量
- # print(x,y)
- #字典
- #python中另一种基本的数据结构是字典,它将值与键联系起来,让我们可以通过键快速找到对应的值
- empty_dict = {} #python风格
- empty_dict2 = dict() #更少的python风格
- grades = {"Joel":80,"Tim":95} #字典
- joels_grade = grades["Joel"] # 80
- # print(joels_grade)
- try:
- kates_grades = grades["Kate"] #如果要找的键不在字典中,会得到KeyError报错
- except KeyError:
- print("no grade for kate!")
- joel_has_grade = "Joel" in grades #True
- kates_has_grade = "Kate" in grades #False
- # print(joel_has_grade, kates_has_grade)
- tweet = { #常常使用字典作为代表结构数据的简单方式
- "user":"joelgrus",
- "text":"Data Science is Awesome",
- "retweet_count":100,
- "hashtags":["#data","#science","#datascience","#awesome","#yolo"]
- }
- tweet_key = tweet.keys() #键的列表 除了查找特定的值,还可以查找所有值
- tweet_values = tweet.values() #值得列表
- tweet_items = tweet.items() #(键,值)元组的列表
- # print(tweet_items)
- print("user"in tweet_key) #True 使用慢速的列表
- print("user"in tweet) #更符合python惯用法,使用快速的字典
- print("joelgrus"in tweet_values) #True
- #defaultdict
- #字典的键不可改变,尤其是不能将列表作为键。如果需要一个多维的键,应该使用元组或设法把键转换成字符串
- document = [] #这是很多单词
- word_counts = {} #这是一个字典
- for word in document: #将列表中的单词进行计数
- if word in word_counts:
- word_counts[word] += 1 #有词就计数加一
- else:
- word_counts[word] = 1 #没词就把词增加到字典中
- word_counts = {}
- for word in document: #当查找缺失值碰到异常报出时,可以遵循“与其瞻前顾后,不如果断行动”的原则,果断处理异常
- try:
- word_counts[word] += 1
- except KeyError:
- word_counts[word] = 1
- word_counts = {}
- for word in document: #用get方法处理缺失值的方法比较优雅
- previous_count = word_counts.get(word,0)
- word_counts[word] = previous_count + 1
- #以上三种方法都略显笨拙,这是defaultdict的意义所在。一个defaultdict相当于一个标准的字典,除了当你查找一个没有包含在内的键时,
- # 它用一个你提供的零参数函数建立一个新的键,并为它的值增加1.
- from collections import defaultdict
- word_counts = defaultdict(int) #int()生成0
- for word in document:
- word_counts[word] += 1
- #这对列表、字典或者自己的函数都有用
- dd_list = defaultdict(list) #list()生成一个空列表
- dd_list[2].append(1) #现在dd_list包含{2:[1]}
- dd_dict = defaultdict(dict) #dict()产生一个新字典
- dd_dict["Joel"]["City"] = "Seattle" #{"Joel":{"City":Seattle}}
- # print(dd_dict)
- dd_pair = defaultdict(lambda :[0,0])
- dd_pair[2][1] = 1 #现在dd_pair包含{2:[0,1]}
- # print(dd_pair) #当我们用字典“收集”某些键对应的结果,并且不希望每次查找某键是否存在都遍历一遍的时候,defaultdict非常有用
- #counter
- #一个计数器将一个序列的值转化成一个类似于整形的标准字典,即defaultdict(int),的键到计数的对象映射。我们主要用它来生成直方图
- from collections import Counter
- c = Counter([0,1,2,0]) #C是(基本的){0:2,1:1,2:1}
- # print(c)
- word_counts = Counter(document) #这给我们提供了一个用来解决单词计数问题的很简便的方法
- for word,count in word_counts.most_common(10): #一个counter实例带有的most_common方法的例子,打印最常见的10个单词和它们的计数
- print(word, count)
- #集合
- # 另一种数据结构是集合(set),它表示为一组不同的元素:
- s = set()
- s.add(1) #s = {1}
- s.add(2) #s = {1,2}
- s.add(2) #s = {1,2} 因为set中元素是不同的
- x = len(s) # x = 2
- y = 2 in s # y = True
- z = 3 in s #z = False
- # print(z)
- #使用集合的原因:1、集合上有一种非常快速的操作:in。如果我们有大量的项目,希望对它的成分进行测试,那么使用集合鄙视用列表合适得多:
- hundreds_of_other_words = [] #这是很多word
- stopwords_list = ["a","an","at"]+hundreds_of_other_words+["yet","you"]
- # print ("zip" in stopwords_list) #False,但需要检查每个元素
- stopwords_set = set(stopwords_list)
- "zip" in stopwords_set #非常快速地检查
- #2、便于在一个汇总中寻找其中离散的项目:
- item_list = [1,2,3,1,2,3]
- num_items = len(item_list) # 6
- item_set = set(item_list) #{1,2,3} 去重
- num_distinct_items = len(item_set) # 3
- distinct_item_list = list(item_set) #[1,2,3]
- #我们使用set的频率远低于dict和list
- #控制流
- if 1>2:
- message = "if only 1 were greater than two..."
- elif 1>3:
- message = "elif stands for 'else if'"
- else:
- message = "when all else fails use else(if yu want to)"
- # print(message)
- parity = "even" if x % 2 == 0 else "odd" #可以在一行语句中使用if-then-else
- # print(parity)
- x = 0
- while x < 10:
- # print(x,"is less than 10")
- x += 1
- # for x in range(10):
- # print(x,"is less than 10")
- for x in range(10):
- if x == 3:
- continue #直接进入下次迭代
- if x == 5:
- break #完全退出循环
- # print(x) # 打印0,1,2,4
- #真和假
- #python的布尔数除了首字母大写之外,其他用法和大多数别的语言类似
- one_is_less_than_two = 1<2
- # print(one_is_less_than_two) #True
- true_equals_false = True == False #False
- # print(true_equals_false)
- x = None #python使用None来表示一个不存在的值,它类似于别的语言中的null
- # print(x == None) # 打印True 但不是python的惯用法
- # print (x is None) #打印True 符合python的惯用法
- #Python可以使用任何可被认为是布尔数的值。下面这些都是“假”(Falsy)
- False,None,[],{},"",set(),0,0.0
- def some_function_that_returns_a_string():
- return "a"
- s = some_function_that_returns_a_string()
- if s:
- first_char = s[0]
- else:
- first_char = ""
- #另一种简单的做法:
- first_char = s and s[0] #第一个值为"真"时,and运算符返回它的第二个值,否则返回第一个值
- # print(first_char)
- safe_x = x or 0 #如果x取值可能是一个数可能是None,返回结果必然是一个数字
- # print(safe_x)
- list = [1,2,3,0] #all函数的取值是一个列表,当列表的每个元素都为真时返回True,any函数取值的列表中至少有一个元素为真时,返回True
- # print(all(list)) #False
- # print(any(list)) #True
- #排序
- x = [4,1,2,3]
- # y = sorted(x) #x不改变
- # print(x,y)
- # x.sort() #x改变
- # print(x,y)
- #默认情况下,sort和sorted给予元素之间的朴素比较从最小值到最大值对列表进行排序
- # 如果想从最大到最小排序,可以指定参数reverse=True。
- # 除了比较元素本身还可以通过指定键来对函数的结果进行比较
- x = sorted([-4,1,-2,3], key = abs, reverse = True) #通过绝对值对列表元素从最大到最小排序
- # print(x) #[-4, 3, -2, 1]
- wc = sorted(word_counts.items(), #从最高数到最低数排序单词和计数
- # key = lambda (word,count):count, #会报错 拓扑参数在python3中不被支持
- reverse = True)
- #列表解析
- #我们有时可能会想把一个列表转换为另一个列表,例如只保留其中一些元素,或更改其中一些元素,
- # 或者同时做这两种变动。可以执行这种操作的python技巧叫做列表解析(list comprehension)
- even_numbers = [x for x in range(5) if x%2 == 0] #[0,2,4]
- squares = [x*x for x in range(5)] #[0,1,4,9.16]
- even_squares = [x*x for x in even_numbers] #[0,4,16]
- # print(even_squares)
- #类似地,可以把列表转换为字典和集合
- square_dict = {x:x*x for x in range(5)} #0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
- squre_set = {x*x for x in [-1,1]} #{1}
- # print(squre_set)
- #如果你不需要来自原列表中的值,常规的方式是使用下划线作为变量
- zeroes = [0 for _ in even_numbers] #和even_number有相同的长度[0, 0, 0]
- # print(zeroes)
- pairs = [(x,y) #列表解析可以包括多个for语句
- for x in range(10)
- for y in range(10)] #100对数据
- # print(pairs)
- #后面的for语句可以使用前面的for语句结果
- increasing_pairs = [(x,y) #只考虑 x<y的对
- for x in range(10) #range(lo,hi)与之相等
- for y in range(x+1,10)] #[lo,lo+1,...,hi-1]
- # print(increasing_pairs)
- #生成器和迭代器
- #生成器(generator)是一种可以对其产生迭代(对我们来说,通常使用for语句)的程序,但是它的值只按需延迟(lazily)产生
- #创建生成器的一种方法时使用函数和yield运算符
- def lazy_range(n):
- """a lazy version of range"""
- i = 0
- while i < n:
- yield i #yield是一个关键词,类似return, 不同之处在于,yield返回的是一个生成器
- i += i
- # print(i)
- # for i in lazy_range(10):
- # i += 1
- # print(i)
- #python确实有一个和lazy_range一样的函数,叫做xrange,并且在python3中,range函数本身就是延迟的,这意味着,你甚至可以创建一个无限的序列
- def natural_numbers():
- """return 1,2,3..."""
- n = 1
- while True: #尽管在没有使用某种break逻辑语句时,不应该做这种迭代
- yield n
- n+=1
- print(n)
- #延迟的缺点是,你只能通过生成器迭代一次。如果需要多次迭代某个对象,你就需要每次都重新创建一个生成器,或者使用列表
- #第二种创建生成器的方法是使用包含在圆括号中的for语句解析:
- lazy_evens_below_20 = (i for i in lazy_range(20) if i%2 == 0)
- lazy_evens_below_20.__next__()
- # print(lazy_evens_below_20) #<generator object <genexpr> at 0x0000000002A4E888>
- def h(n):
- while n>0:
- m = (yield n)
- print ("m is "+str(m))
- n-=1
- print ("n is "+str(n))
- p= h(5)
- p.__next__()
- p.send("test")
- p.__next__()
- #随机性
- import random
- four_uniform_randoms = [random.random() for _ in range(4)] #random.random()生成在0-1之间均匀分布的随机数,是最常见的随机函数
- # print(four_uniform_randoms) #[0.8409394478222172, 0.8725989680572983, 0.43909368270992066, 0.9883409909539946]
- #random模块实际上生成的是基于一种内部状态的确定性的伪随机数。如果你想得到可复生的结果,可以用random.seed生成随机数种子:
- random.seed(10) #设置随机数种子为10
- print(random.random()) #0.5714025946899135
- random.seed(10) #重设随机数种子为10
- print(random.random()) #再次得到0.5714025946899135
- #有时候我们用random.randrange生成随机数,它会取1到2个参数,并从对应的range()函数随机选择一个元素返回:
- print(random.randrange(10)) #从range(10) = [0,1,...,9]中随机选取
- print(random.randrange(3,6)) #range(3,6)= [3,4,5]中随机选取
- #random.shuffle可随机地重排列表中的元素:
- up_to_ten = [4,1,3,5,7,8]
- random.shuffle(up_to_ten) # [8, 3, 5, 1, 4, 7] shuffle不支持range重排列
- print(up_to_ten)
- my_best_friend = random.choice(["Alice","Bob","Charlie"]) #从列表中随机取一个元素
- print(my_best_friend)
- lottery_numbers = range(60)
- winning_numbers = random.sample(lottery_numbers, 6) #[41, 51, 10, 2, 33, 31] 不重复地随机选择一个元素的样本,可以使用random.sample
- print(winning_numbers)
- four_with_replacement = [random.choice(range(10)) #[5, 1, 3, 5] 选择一个允许重复的元素样本,只需多次调用random.choice即可
- for _ in range(4)]
- print(four_with_replacement)
- #正则表达式
- import re
- print(all([ #所有这些语句都为True,因为
- not re.match("a","cat"), #* 'cat'不以'a'开头
- re.search("a","cat"), #* 'cat'里有一个字符'a'
- not re.search("c","dog"), #*'dog'里没有字符'c'
- 3 == len(re.split("[ab]","carbs")), #*分割掉a,b,剩余长度为3
- "R-D-" == re.sub("[0-9]","-","R2D2") #用虚线进行位的替换
- ]))
- #面向对象编程
- class Set:
- #这些是成员函数
- #每个函数都取第一个参数"self"(另一种惯例)
- #它表示所用到的特别的集合对象
- def __init__(self, values = None):
- """this is the constructor.
- It gets called when you create a new set.
- you would use it like
- s1 = Set() #空集合
- s2 = Set([1,2,2,3]) #用值初始化"""
- self.dict = {} #Set的每一个实例都有自己的dict属性
- #我们会用这个属性来追踪成员关系
- if values is not None:
- for value in values:
- self.add(value)
- def __repr__(self):
- """this is the string representation of a Set object
- if you type it at the Python prompt or pass it to str()"""
- return ("Set:",str(self.dict.keys()))
- #通过成为self.dict中对应值为True的键,来表示成员关系
- def add(self, value):
- self.dict[value] = True
- #如果它在字典中是一个键,那么在集合中就是一个值
- def contains(self, value):
- return value in self.dict
- def remove(self, value):
- del self.dict[value]
- s = Set([1,2,3])
- s.add(4)
- print(s.contains(4)) #True
- s.remove(3)
- print(s.contains(3)) #False
- #函数式工具 部分地应用函数创建新函数
- def exp(base, power):
- return base ** power
- def two_to_the(power):
- return (exp(2,power))
- # print(two_to_the(3)) # 8
- from functools import partial
- two_to_the = partial(exp,2)
- # print(two_to_the(3)) # 8
- square_of = partial(exp,power = 2)
- # print(square_of(3)) # 9
- def double(x):
- return x*x
- xs = [1,2,3,4]
- twice_xs = [double(x) for x in xs] #[1, 4, 9, 16]
- twice_xs = list(map(double,xs)) #python3中输出的是map对象,如果想跟list一样输出,需要转为list
- list_doubler = partial(map ,double)
- twice_xs = list_doubler(xs)
- # print(list(twice_xs))
- def multiply(x,y):return x*y
- products = map(multiply,[1,2],[4,5]) # 1*4 2*5 [4, 10]
- # print(list(products))
- def is_even(x):
- """True if x is even , False if x is odd"""
- return x%2 == 0
- x_evens = [x for x in xs if is_even(x)] #[2, 4]
- x_evens = filter(is_even,xs) #<filter object at 0x00000000049294E0>
- # print(list(x_evens)) #[2, 4]
- list_evener = partial(filter,is_even)
- x_evens = list_evener(xs)
- # print(list(x_evens)) #[2, 4]
- import functools
- x_product = functools.reduce(multiply,xs) #python3把reduce放在了functools包中,功能:一步步计算
- list_product = partial(functools.reduce,multiply)
- x_product = list_product(xs)
- # print(x_product) # 24
- #枚举
- #有时候可能想在一个列表上迭代,并且同时使用它的元素和元素的索引
- #非python用法
- documents = "" #这是一个文档
- for i in range(len(documents)):
- document = documents[i]
- print(document)
- #非python用法
- i = 0
- for document in documents:
- print(document,i)
- i += 1
- #python惯用的解决方案是使用枚举(enumerate),它会产生(index,element)元组:
- for i, document in enumerate(documents):
- print(i,document)
- #类似的,如果只想要索引,则执行
- for i in range(len(documents)):print(i) #非python用法
- for i, _ in enumerate(documents):print(i) #python用法
- #压缩和参数拆分
- #如果想把两个或多个列表压缩到一起,可以使用zip把多个列表转换为一个对应元素的元组的单个列表中
- list1 = ['a', 'b', 'c']
- list2 = [1,2,3,4] #如果列表的长度各异,zip会在第一个列表结束时停止
- z = zip(list1,list2)
- # print(list(z)) #[('a', 1), ('b', 2), ('c', 3)]
- #可以用一种特殊的方法解压列表
- list3, list4 = zip(*z) #*执行参数拆分(argument unpacking)
- # print(list3, list4) #('a', 'b', 'c') (1, 2, 3)
- #可以在任何函数上使用参数拆分
- def add(a, b):return a + b
- # print(add(1,2)) # 3
- # print(add([1,2])) #TypeError
- # print(add(*[1,2])) #3
- #args和kwargs
- #假如我们想创建一个更高阶的函数,把某个函数f作为输入,并返回一个对任意输入都返回f值两倍的新函数
- def doubler(f):
- def g(x):
- return 2*f(x)
- return g
- def f1(x):
- return x+1
- g = doubler(f1)
- # print(g(3)) # 8
- # print(g(-1)) # 0
- def f2(x,y):
- return x+y
- # g = doubler(f2) #TypeError: g() takes 1 positional argument but 2 were given
- # print(g(1,2))
- def magic(*args, **kwargs):
- print("unnamed args:",args)
- print("keyword args:",kwargs)
- magic(1,2,key = "word", key2 = "word2") # unnamed args: (1, 2)
- # keyword args: {'key': 'word', 'key2': 'word2'}
- def other_way_magic(x,y,z):
- return x+y+z
- x_y_list = [1,2]
- z_dict = {"z":3}
- # print(other_way_magic(*x_y_list,**z_dict)) # 6
- #我们将会只用它来创建可以将任意参数作为输入的高阶函数
- def doubler_correct(f):
- """works no matter what kind of inputs of expects"""
- def g(*args, **kwargs):
- """whatever arguments g is supplied, pass them through to f"""
- return 2*f(*args,**kwargs)
- return g
- g = doubler_correct(f2) # 6
- # print(g(1,2))
- exit(0)
python笔记
最新推荐文章于 2020-12-07 21:31:31 发布