python的基本语法上
在学习数据处理方面比较好或者说比较火的语言当然是python了,而且还比较容易上手。之前看过部分代码但是,已经扔下好久了,正好这次跟着居士把python重新学习一遍,可以说转行数据挖掘,,,Python必须会吧
在这里欢迎大家关注公众号 木东居士 这次的活动也是居士发起的,一位技术大佬,一起来吹牛吧~
废话不多说 我们开始学习,Python部分主要还是根据《利用Python进行数据分析》第二、三章的知识
链接如下第02章 Python语法基础,IPython和Jupyter Notebooksseancheney.gitbook.io
如果想入门也可以看 廖雪峰老师的官方教程
链接如下 :Python基础www.liaoxuefeng.com
一、python 的安装
有关python的IDE问题这里推荐使用Annacoda中的jupyter,如果大家使用别的也是可以滴,下面开始我们的第一行代码,如果我们经过安装,得到正确的结果---hello world 那说明python的安装已经完成啦
print('hello world')
hello world
前边部分笔者直接复制《利用Python进行数据分析》这本书上的知识,主要是为了防止后面有东西遗忘再次提醒的作用如果有不详细,请大家翻阅此书
python自省
在变量前后使用问号?,可以显示对象的信息:(而且可以显示自定义函数的注释信息!!!以及在变量后面使用??可以显示源代码)
我们写如下的函数
然后使用?就可以显示如下的文档字符串
使用??就可以显示函数的源码
%run命令
你可以用%run命令运行所有的Python程序。假设有一个文件hello.py:
文件内容:
a=10
print('hello world')
如果想在jupyter中运行此文件需要用到%run 命令
用法如下(这里需要注意所运行的文件必须要和你的jupyter文件(.ipython格式)在同一个文件夹中,不然会报can't search file错误)
%run hello.py
Hello World
注
%run方式文件中所有定义的变量(import、函数和全局变量,除非抛出异常),都可以在IPython shell中随后访问:
a
10
%load命令
在Jupyter notebook中,你也可以使用%load,它将脚本导入到一个代码格中:
# %load hello.py
a =10
print('Hello World')
中间途中对python 中sys.argv的用法略有研究
Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数。
链接详解sys.argv详解blog.csdn.net
魔术命令
IPython中特殊的命令(Python中没有)被称作“魔术”命令。这些命令可以使普通任务更便捷,更容易控制IPython系统。魔术命令是在指令前添加百分号%前缀。例如,可以用%timeit(这个命令后面会详谈)测量任何Python语句,例如矩阵乘法,的执行时间:
import numpy as np
a = np.random.randn(100,100)
%timeit np.dot(a,a)
20.4 µs ± 6.72 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
可以通过?查看一个具体的魔术命令的使用比如说 %debug?
集成Matplotlib
IPython在分析计算领域能够流行的原因之一是它非常好的集成了数据可视化和其它用户界面库,比如matplotlib。%matplotlib魔术函数配置了IPython shell和Jupyter notebook中的matplotlib。这点很重要,其它创建的图不会出现(notebook)或获取session的控制,直到结束(shell)。
在jupyter中设置Matplotlib
%matplotlib inline
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(np.random.randn(50).cumsum())
二、Python的语法基础
使用缩进,而不是括号
Python使用空白字符(tab和空格)来组织代码,而不是像其它语言,比如R、C++、JAVA和Perl那样使用括号。看一个排序算法的for循环:
for x in array:
if x < pivot:
less.append(x)
else:
greater.append(x)
冒号标志着缩进代码块的开始,冒号之后的所有代码的缩进量必须相同,直到代码块结束。不管是否喜欢这种形式,使用空白符是Python程序员开发的一部分,在我看来,这可以让python的代码可读性大大优于其它语言。虽然期初看起来很奇怪,经过一段时间,你就能适应了。
万物皆对象
Python语言的一个重要特性就是它的对象模型的一致性。每个数字、字符串、数据结构、函数、类、模块等等,都是在Python解释器的自有“盒子”内,它被认为是Python对象。每个对象都有类型(例如,字符串或函数)和内部数据。在实际中,这可以让语言非常灵活,因为函数也可以被当做对象使用。
python 注释(分为单行注释和多行注释)
单行注释
使用#符号
多行注释
使用''' '''符号
变量和参数传递
当在Python中创建变量(或名字),你就在等号右边创建了一个对这个变量的引用。考虑一个整数列表:
a = [1, 2, 3]
假设将a赋值给一个新变量b:
b = a
在有些方法中,这个赋值会将数据[1, 2, 3]也复制。在Python中,a和b实际上是同一个对象,即原有列表[1, 2, 3]。你可以在a中添加一个元素,然后检查b:
a.append(4)
b
[1, 2, 3, 4]
理解Python的引用的含义,数据是何时、如何、为何复制的,是非常重要的。尤其是当你用Python处理大的数据集时。
#### 笔记:赋值也被称作绑定,我们是把一个名字绑定给一个对象。变量名有时可能被称为绑定变量。
当你将对象作为参数传递给函数时,新的局域变量创建了对原始对象的引用,而不是复制。如果在函数里绑定一个新对象到一个变量,这个变动不会反映到上一层。因此可以改变可变参数的内容。假设有以下函数:
动态引用,强类型
与许多编译语言(如JAVA和C++)对比,Python中的对象引用不包含附属的类型。下面的代码是没有问题的:
变量是在特殊命名空间中的对象的名字,类型信息保存在对象自身中。一些人可能会说Python不是“类型化语言”。这是不正确的,看下面的例子:
在某些语言中,例如Visual Basic,字符串‘5’可能被默许转换(或投射)为整数,因此会产生10。但在其它语言中,例如JavaScript,整数5会被投射成字符串,结果是联结字符串‘55’。在这个方面,Python被认为是强类型化语言,意味着每个对象都有明确的类型(或类),默许转换只会发生在特定的情况下,例如:
知道对象的类型很重要,最好能让函数可以处理多种类型的输入。你可以用isinstance函数检查对象是某个类型的实例:
isinstance可以用类型元组,检查对象的类型是否在元组中:
鸭子类型
经常地,你可能不关心对象的类型,只关心对象是否有某些方法或用途。这通常被称为“鸭子类型”,来自“走起来像鸭子、叫起来像鸭子,那么它就是鸭子”的说法。例如,你可以通过验证一个对象是否遵循迭代协议,判断它是可迭代的。对于许多对象,这意味着它有一个iter魔术方法,其它更好的判断方法是使用iter函数:
def isiterable(obj):
try:
iter(obj)
return True
except TypeError:
return False
这个函数会返回字符串以及大多数Python集合类型为True:
isiterable(1)
False
我总是用这个功能编写可以接受多种输入类型的函数。常见的例子是编写一个函数可以接受任意类型的序列(list、tuple、ndarray)或是迭代器。你可先检验对象是否是列表(或是NUmPy数组),如果不是的话,将其转变成列表:
二元运算符和比较运算符
python二元运算符和比较运算符如下表所示(注意区分is(is not)与==,一个是值之间的比较一个是引用对象之间的比较)
可变对象与不可变对象
Python中的大多数对象,比如列表、字典、NumPy数组,和用户定义的类型(类),都是可变的。意味着这些对象或包含的值可以被修改:
list1 = [1,3,45,6]
print(list1)
list1[0] = 10
print(list1)
[1, 3, 45, 6]
[10, 3, 45, 6]
其它的,例如字符串和元组,是不可变的:
tuple1 = (1,2,34,5)
tuple1[0]
tuple[0]=3 # 错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
1 tuple1 = (1,2,34,5)
2 tuple1[0]
----> 3 tuple[0]=3
TypeError: 'type' object does not support item assignment
str1 ="asdasd"
str1[0]
str1[0]="s" # 错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
1 str1 ="asdasd"
2 str1[0]
----> 3 str1[0]="s"
TypeError: 'str' object does not support item assignment
标量类型
Python的标准库中有一些内建的类型,用于处理数值数据、字符串、布尔值,和日期时间。这些单值类型被称为标量类型,本书中称其为标量。表列出了主要的标量。日期和时间处理会另外讨论,因为它们是标准库的datetime模块提供的。
数值类型
Python的主要数值类型是int和float。int可以存储任意大的数:
i = 1231241241412414
i*i
1515954994554782331501633307396
浮点数使用Python的float类型。每个数都是双精度(64位)的值。也可以用科学计数法表示:
fval1 = 2.321321
fval2 = 2.3e-5
不能得到整数的除法会得到浮点数:
3/2
1.5
要获得C-风格的整除(去掉小数部分),可以使用底除运算符//:
3 //2
1
字符串
Python具有强大而灵活的字符串处理。你可以用单引号或双引号来写字符串:
a = 'one way of writing a string'
b = "another way"
对于有换行符的字符串,可以使用三引号,'''或"""都行:
c = """This is a longer string thatspans multiple lines"""
字符串c实际包含四行文本,"""后面和lines后面的换行符。可以用count方法计算c中的新的行:
c.count('\n')
3
Python的字符串是不可变的,不能修改字符串:
a = 'this is a string'
a[10] = 'f'
经过以上的操作,变量a并没有被修改:
a
'this is a string'
许多Python对象使用str函数可以被转化为字符串:
a = 5.6
s = str(a)
print(s)
5.6
字符串是一个序列的Unicode字符,因此可以像其它序列,比如列表和元组(下一章会详细介绍两者)一样处理:
s = 'python'
l= list(s)
print(l)
l[:3]
['p', 'y', 't', 'h', 'o', 'n']
['p', 'y', 't']
语法l[:3]被称作切片,适用于许多Python序列。后面会更详细的介绍,本书中用到很多切片。
反斜杠是转义字符,意思是它备用来表示特殊字符,比如换行符\n或Unicode字符。要写一个包含反斜杠的字符串,需要进行转义:
s = '12\\34'
print(s)
12\34
如果字符串中包含许多反斜杠,但没有特殊字符,这样做就很麻烦。幸好,可以在字符串前面加一个r,表明字符就是它自身:
s = r'this\has\no\special\characters'
s
'this\\has\\no\\special\\characters'
r表示raw
将两个字符串合并,会产生一个新的字符串:
a = 'this is the first half '
b = 'and this is the second half'
a+b
'this is the first half and this is the second half'
重点
字符串的模板化或格式化,是另一个重要的主题。Python 3拓展了此类的方法,这里只介绍一些。字符串对象有format方法,可以替换格式化的参数为字符串,产生一个新的字符串:
template = '{0:.2f} {1:s} are worth US${2:d}'
在这个字符串中,{0:.2f}表示格式化第一个参数为带有两位小数的浮点数。
{1:s}表示格式化第二个参数为字符串。
{2:d}表示格式化第三个参数为一个整数。
要替换参数为这些格式化的参数,我们传递format方法一个序列:
template.format(4.5560, 'Argentine Pesos', 1)
'4.56 Argentine Pesos are worth US$1'
字节和Unicode
在Python 3及以上版本中,Unicode是一级的字符串类型,这样可以更一致的处理ASCII和Non-ASCII文本。在老的Python版本中,字符串都是字节,不使用Unicode编码。假如知道字符编码,可以将其转化为Unicode。看一个例子:
val = 'asdaasd'
val
'asdaasd'
可以用encode将这个Unicode字符串编码为UTF-8:
val_utf8 = val.encode('utf-8')
val_utf8
b'asdaasd'
type(val_utf8)
bytes
如果你知道一个字节对象的Unicode编码,用decode方法可以解码:
val_utf8.decode('utf-8')
'asdaasd'
布尔值
Python中的布尔值有两个,True和False。比较和其它条件表达式可以用True和False判断。布尔值可以与and和or结合使用
类型转换
str、bool、int和float也是函数,可以用来转换类型:
s = '3.14159'
f = float(s)
type(f)
float
日期和时间
Python内建的datetime模块提供了datetime、date和time类型。datetime类型结合了date和time,是最常使用的:
from datetime import datetime,date,time
dt = datetime(2011, 10, 29, 20, 30, 21)
dt.day
29
dt.minute
30
根据datetime实例,你可以用date和time提取出各自的对象:
dt.date()
datetime.date(2011, 10, 29)
dt.time()
datetime.time(20, 30, 21)
strftime方法可以将datetime格式化为字符串:
dt.strftime('%m/%d/%Y %H:%M')
'10/29/2011 20:30'
strptime可以将字符串转换成datetime对象:
datetime.strptime('20091031', '%Y%m%d')
datetime.datetime(2009, 10, 31, 0, 0)
表列出了所有的格式化命令。
当你聚类或对时间序列进行分组,替换datetimes的time字段有时会很有用。例如,用0替换分和秒:
dt.replace(minute=0, second=0)
datetime.datetime(2011, 10, 29, 20, 0)
因为datetime.datetime是不可变类型,上面的方法会产生新的对象。
两个datetime对象的差会产生一个datetime.timedelta类型:
dt2 = datetime(2011, 11, 15, 22, 30)
delta =dt2-dt
delta
datetime.timedelta(days=17, seconds=7179)
type(delta)
datetime.timedelta
结果timedelta(17, 7179)指明了timedelta将17天、7179秒的编码方式。
将timedelta添加到datetime,会产生一个新的偏移datetime:
dt
datetime.datetime(2011, 10, 29, 20, 30, 21)
dt + delta
datetime.datetime(2011, 11, 15, 22, 30)
控制流
Python有若干内建的关键字进行条件逻辑、循环和其它控制流操作。
if、elif和else
if是最广为人知的控制流语句。它检查一个条件,如果为True,就执行后面的语句:
x =5
if x > 0:
print(1)
x=x-1
1
if后面可以跟一个或多个elif,所有条件都是False时,还可以添加一个else:
if x < 0:
print('It\'s negative')
elif x == 0:
print('Equal to zero')
elif 0 < x < 5:
print('Positive but smaller than 5')
else:
print('Positive and larger than or equal to 5')
Positive but smaller than 5
如果某个条件为True,后面的elif就不会被执行。当使用and和or时,复合条件语句是从左到右执行:
a = 5; b = 7
c = 8; d = 4
if a < b or c > d:
print('Made it')
Made it
在这个例子中,c > d不会被执行,因为第一个比较是True:
也可以把比较式串在一起:
4 > 3 > 2 > 1
True
for循环
for循环是在一个集合(列表或元组)中进行迭代,或者就是一个迭代器。for循环的标准语法是:
for value in collection:
# do something with value
你可以用continue使for循环提前,跳过剩下的部分。看下面这个例子,将一个列表中的整数相加,跳过None:
sequence = [1, 2, None, 4, None, 5]
total = 0
for value in sequence:
if value is None:
continue
total += value
total
12
可以用break跳出for循环。下面的代码将各元素相加,直到遇到5:
sequence = [1, 2, 0, 4, 6, 5, 2, 1]
total_until_5 = 0
for value in sequence:
if value == 5:
break
total_until_5 += value
break只中断for循环的最内层,其余的for循环仍会运行:
for i in range(4):
for j in range(4):
if j > i:
break
print((i, j))
(0, 1)
(1, 2)
(2, 3)
(3, 3)
如果集合或迭代器中的元素序列(元组或列表),可以用for循环将其方便地拆分成变量:
for a, b, c in iterator:
# do something
While循环
while循环指定了条件和代码,当条件为False或用break退出循环,代码才会退出:
x = 256
total = 0
while x > 0:
if total > 500:
break
total += x
x = x // 2
pass
pass是Python中的非操作语句。代码块不需要任何动作时可以使用(作为未执行代码的占位符(说白了就是为了写写整个代码框架而准备的));因为Python需要使用空白字符划定代码块,所以需要pass:
if x < 0:
print('negative!')
elif x == 0:
# TODO: put something smart here
pass
else:
print('positive!')
positive!
range
range函数返回一个迭代器,它产生一个均匀分布的整数序列:
range(10)
range(0, 10)
list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range的三个参数是(起点,终点,步进):
list(range(0, 20, 2))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
list(range(5, 0, -1))
[5, 4, 3, 2, 1]
可以看到,range产生的整数不包括终点。range的常见用法是用序号迭代序列:
seq = [1, 2, 3, 4]
for i in range(len(seq)):
val = seq[i]
可以使用list来存储range在其他数据结构中生成的所有整数,默认的迭代器形式通常是你想要的。下面的代码对0到99999中3或5的倍数求和:
sum = 0
for i in range(100000):
# % is the modulo operator
if i % 3 == 0 or i % 5 == 0:
sum += i
虽然range可以产生任意大的数,但任意时刻耗用的内存却很小。
三元表达式
Python中的三元表达式可以将if-else语句放到一行里。语法如下:
value = true-expr if condition else false-expr
true-expr或false-expr可以是任何Python代码。它和下面的代码效果相同:
if condition:
value = true-expr
else:
value = false-expr
下面是一个更具体的例子:
x = 5
'Non-negative' if x >= 0 else 'Negative'
'Non-negative'
和if-else一样,只有一个表达式会被执行。因此,三元表达式中的if和else可以包含大量的计算,但只有True的分支会被执行。因此,三元表达式中的if和else可以包含大量的计算,但只有True的分支会被执行。
虽然使用三元表达式可以压缩代码,但会降低代码可读性。