2022年8月18日22:45:19
Q:在ipython中运行run试的时候,无法成功会出现如下错误提示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fWBF7YLk-1661576171052)(C:\Users\光明斗士\AppData\Roaming\Typora\typora-user-images\image-20220818224816164.png)]
A
由于python2.x和python3.x在print语句上有语法差别;
pyhon2.x : print"hello,world"无需加上括号;
python3.x :print(“hello,world”)需加括号;
所以文件的写入应该为
%%writefile helllo_world.py
print(“hello world”)
Q 返回上一层文件的命令。
A %cd(空格)…(空格)。
Q 使用matplotlib画的图这么找?还是说显示不出来图像,目前不知道原因。
A
Q Python中有一种叫做列表推导式(List comprehension)的用法,还是咩很看懂。
Q notebook打不开?
anaconda环境切换
一、先创建一个新的虚拟环境
conda create --name my_test python=3.7#创建一个名称为my_test
二、激活虚拟环境
activate my_test
三、查看环境
conda env list
-位于括号中的指针可以直接通过回车直接跳转到最后的位置。
-如果需要在文字中插入括号可以直接选中插入括号。
-需要跳过间冒号可以在按一次冒号。
-对于单引号''
,在输入完单引号的内容之后可以再摁单引号‘
即可将光标对到单引号之外,对于所有的对称符号都可以这样处理,包括[]
,""
,{}
。
python2.7中整型运算只能返回整型,包括除法。
12/5
2#python2.7
2.4#python3.7
幂指数
2**5
32
取余
32%5
2
整数除浮点数得到浮点数。
12/5.0
2.4
在python中用j
来表示虚部。
a = 1+2j
实部
a.real
虚部
a.imag
共轭(实部相同,虚部相反)
a.conjugate()
布尔型数据取特殊的二值变量,为true
和false
。
字符串采用单引号’'或者双引号""均可以生成字符串,而且相同,任何地方使用到字符串均需要带引号。
s = "hello world"
s = 'hello world'
s = ’hello‘ + 'world'
print (s)
'hello world'
"echo"*3
'echoechoecho'
len(s)
面向对象的语言,其中一个不可少的元素就是方法。
方法调用方式如下:
对象.方法()
s.split(sep)将按照给定的sep为分隔符对s进行分割,返回一个列表
其中sep可以是空格(sep不写默认值)也可是制表符\t
换行符\n
。
line = "1 2 3 4 5"
numbers = line.split()
print numbers
['1','2','3','4','5'] #返回值是列表list
按照sep给定的内容分割 需要加个单引号''
。
line = "1,2,3,4,5"
numbers = line.split(',')
print numbers
['1','2','3','4','5'] #返回值是列表list
和分割相反,s.join(str_sequence)的作用就是将s中的每两个字符串元素用str_sequence连接起来,返回连接后的字符串。
numbers = "12345"
s = ','
s.join(numbers)
'1,2,3,4,5'
s.replace(part1,part2)将字符串s中的part1替换成part2,并返回替换后的字符串。
s = "hello world"
s.replace('world','python')
'hellow pthyon'
大小写转换
s.upper()返回一个将s中的字母全部大写的新字符串,不改变原始值。
"hello world".upper()
'HELLO WORLD'
s.lower()返回一个将s中的字母全部小写的新字符串,不改变原始值。
"HELLO WORLD".lower()
'hello world'
s.strip()返回一个去除s两端多余空格的新字符,不改变原始值。
s = " hello world "
s.strip()
'hello world'
s.lstrip()返回一个去除s开头多余空格的新字符,不改变原始值。
s = " hello world "
s.lstrip()
'hello world '
s.rstrip()返回一个去除s开头多余空格的新字符,不改变原始值。
s = " hello world "
s.rstrip()
' hello world'
Python采用一堆”“”
或者‘‘‘
来生成多行字符串。
a = '''hello world,
what a nice day!!'''
print(a)
hello world,
what a nice day!!
str(ob)
强制将ob
转化成字符串。
repr(ob)
也是强制将ob
转化成字符串。
str(1.1 + 2.2)
'3.3'
repr(1.1 + 2.2)
'3.3000000000000003'
对于一个有序序列,我们可以通过索引的方式访问对应位置的数值。Python采用[]
对有序序列索引。
并且Python中的索引是从0
开始的,所以[0]
对应序列的第1
个元素。
(可以这么理解,索引指针这在初始位置0
处,第1
个元素
[0]
就表示移动0
个距离;
[1]
表示正向移动一个距离,所以[1]
表示的是第2
个元素;
[-1]
表示负向移动一个距离,所以指向字符串最后一个)
s = "hellow world"
s[0]
'h'
[5]
对应的是第四个元素。
s[5]
'l'
并且Python还支持负向索引,从后向前开始计数,索引[-2]
表示倒数第2
个元素,和正向的需要-1运算不相同。
s[-2]
'l'
超出索引值会报错:
s[11]
IndexError: string index out of range
分片表示从序列中提取出需要的子序列,具体方法为:
var[lower:upper:step]
范围包括lower
,不包括upper
,就是[lower,upper)
,step
表示间距,通常不写,默认为1
s = [hello world]
其中元素为 个数为upper-lwer 并且 每个数可以为负数。
lower为负数可以表示从倒数第三个开始,由于省略upper,所以需要计数到end
s = [-3:]
'rld'#表示从倒数第3个开始到结尾结束
uppper为负数可以表示到倒数第三个为止,由于省略lower,所以需要从start计数
s = [:-3]
'hello wor'#表示从开头到里结尾3个
当step的值为负时,省略lower意味着从结尾开始分片,省略upper意味着一直分片到开头。?
s[::-1]
'dlrow olleh'
使用in
来判断某个元素是否在某个序列中:
s = "hello world"
print('he' in s)
True
用not in
来判断某个元素是否不在某个序列中:
s = "hello world"
print('he' not in s)
False
Python中,列表(list)是一个有序可以包含不同数据类型(整型,字符串,浮点)的序列。
列表用一对 []
生成,中间的元素用 ,
隔开,其中的元素不需要是同一类型,同时列表的长度也不固定,列表长度是采用,
区分的。
列表输出可以直接输出列表名字或者采用print()
两种方式。
l = [1,2.0,'hello']
print(l)
[1, 2.0, 'hello']
空列表可以采用[]
或者list()
生成:
empty_list = []
empty_list
[]
empty_list = list()
print(empty_list)
[]
此阿勇len()
来查看列表长度,列表长度取决于,
分割内容:
l = [1,2.0,'hello']
len(l)
3
列表加法,相当于两个列表顺序相加:
a = [1,2,3]
b = [3.2,'hello']
a + b
[1, 2, 3, 3.2, 'hello']
列表和和数字相乘,基本相当于列表的重复相加:
a = [1,2,3]
a*2
[1, 2, 3, 1, 2, 3]
列表和字符串一样可以通过索引来查看元素值:
正向索引
a = [1,2,3,4,5,6]
a[0]
1
反向索引
a[-1]
6
a[2:-1]
[3, 4]
与字符串的不同之处是,列表值可以通过索引和分片来修改。
索引修改:
a = [1,2,3,4,5]
a[0] = 100
a
[100, 2, 3, 4, 5]
分片修改:
a[1:3] = [11,12]
a
[100, 11, 12, 4, 5]
事实上,对于连续的分片(即步长为 1
),Python采用的是整段替换的方法,两者的元素个数并不需要相同,例如,将 [11,12]
替换为 [1,2,3,4]
:
a = [10,11,12,13,14]
a[1:3] = [1,2,3,4]
a
[10, 1, 2, 3, 4, 13, 14]
也可以采用这种方式删除一个连续的分片:
a = [10,1,2,11,12]
a[1:3]
a[1:3] = []
a
[1, 2]
[10, 11, 12]
对于不连续(间隔step不为1)的片段进行修改时,两者的元素数目必须一致:
a = [19,11,12,13,14]
a[::2] = [1,2,3]
a
[1, 11, 2, 13, 3]
否则会报错
a = [19,11,12,13,14]
a[::2] = []
a
ValueError: attempt to assign sequence of size 0 to extended slice of size 3
Python提供了删除列表中元素的方法 ‘del’。
删除列表中的第一个元素:
a = [1002,'a','b','c']
del a[0]
a
['a', 'b', 'c']
删除第2到最后一个元素:
a = [1002,'a','b','c']
del a[1:]
a
[1002]
删除间隔的元素
a = ['a',1,'b',2,'c']
del a[::2]
a
[1, 2]
使用in
来判断某个元素是否在某个序列中:
a = [10,11,12,13,14]
print (10 in a)
True
用not in
来判断某个元素是否不在某个序列中:
a = [10,11,12,13,14]
print (10 not in a)
False
列表中甚至可以包含列表:
a = [10,'eleven',[12,13]]
a[2]
[12, 13]
a[2]
是一个列表,可以在对它进行索引:
a[2][1]
13
l.count(ob)
返回列表元素ob
出现的次数。
a = [11,12,13,12,11]
a.count(11)
2
需要查询列表中的列表出现的次数:
a = [11,12,13,12,11,[11,12,13,12,11]]
a[5].count(11)
2
l.index(ob)
返回列表中元素 ob
第一次出现的索引位置,如果 ob
不在 l
中会报错。
a.index(12)
1
l.append(ob)
将元素 ob
添加到列表 l
的最后。
a = [10,11,12]
a.append(11)
print(a)
[10, 11, 12, 11]
append
每次只添加一个元素,并不会因为这个元素是序列而将其展开:
a.append([11,12])
print(a)
[10, 11, 12, 11, [11, 12]]
l.extend(lst)
将序列 lst
的元素依次添加到列表 l
的最后,作用相当于 l += lst
。
a = [10,11,12,11]
a.extend([1,2])
print(a)
[10, 11, 12, 11, 1, 2]
l.insert(idx, ob)
在索引 idx
处插入 ob
,之后的元素依次后移。
note:idx的计数方式不和索引相同,从第一个开始计数
a = [10,11,12,13,11]
a.insert(3,'a')
print(a)
[10, 11, 12, 'a', 13, 11]
l.remove(ob)
会将列表中第一个出现的 ob
删除,如果 ob
不在 l
中会报错。
a = [10,11,12,13,11]
a.remove(11)
print(a)
[10, 12, 13, 11]
l.pop(idx)
会将索引 idx
处的元素删除,idx的数值与索引相同,均为从0计数,并返回这个元素。
a = [10,11,12,13,11]
a.pop(2)
12
l.sort()将会按照一定的规则排序,并会改变原来的值:
a = [10,1,11,13,11,2]
a.sort()
print(a)
[1, 2, 10, 11, 11, 13]
如果想不改变原来的顺序,可以使用sorteed()
函数:
a = [10,1,11,13,11,2]
b = sorted(a)
print(a)
print(b)
[10, 1, 11, 13, 11, 2]
[1, 2, 10, 11, 11, 13]
l.reverse()将会将列表的元素从后向前排列,会改变原来的值:
a = [1,2,3,4,5,6]
a.reverse()
print(a)
[6, 5, 4, 3, 2, 1]
如果不想改变原来的值,可以使用分片的方法:
a = [1,2,3,4,5,6]
b = a[::-1]
print(a)
print(b)
[1, 2, 3, 4, 5, 6]
[6, 5, 4, 3, 2, 1]
与列表相似,元组tuple也是一个有序序列,但是元组是不可变的,采用()
表示:
t = (10,11,12,13,14)
t
(10, 11, 12, 13, 14)
元组可以索引:
t(0)
10
可以切片:
t[1:3]
(11, 12)
但是元组是不可变的。
由于元组采用()
,所以,采用以下形式定义单个元组:
a = (10,)
print(a)
type(a)
(10,)
<type 'tuple'>
而非:
a = (10)
print (type(a))
<type 'int'>
将列表转换成元组:
a = [10,11,12,13,14]
tuple(a)
(10, 11, 12, 13, 14)
由于元组是不可变的,所以只能有一些不可变的方法,例如计算元素个数 count
和元素位置 index
,用法与列表一样。
a = [10,11,12,13,14]
a.count(10)
1
a = [10,11,12,13,14]
a.index(12)
2
速度部分:元组只是生成速度快一点,遍历和索引速度向差不多。
字典 dictionary
,在一些编程语言中也称为 hash
, map
,是一种由键值对组成的数据结构。
可以把key想象成字典里面的单词,把value想象成单词对应对的定义,所以,一个词可以对应一个或者多个定义。
在Python中采用{key:value}
生成dictionary:
d = {'dog':5,'cat':4}
d
type(d)
{'dog': 5, 'cat': 4}
dict
生成一个空字典:
a = {}
a
{}
或者采用定义:
a = dict()
a
{}
查询一个字典的大小,字典的大小表示一组键值的大小:
d = {'dog':5,'cat':4}
len(d)
2
d["dog"]
5
d["dog"] = 2
d
{'dog': 2, 'cat': 4}
可以直接在一个字典之后继续输入键值:
d["pigs"] = 7
d
{'dog': 2, 'cat': 4, 'pigs': 7}
-字典是没有顺序的,在我们Print
一个字典,他并一定会按照键值的先后顺序显示,因为建本身不一定有序。
-键必须是不可变的类型,整型和字符串是字典中最常用的,值可以是任意类型的。
get
返回值get
用来索引一个字典的键值,当字典中的键不存在时,便会报错,在报错的时候,get
便可以来处理,返回给定的报错:
d.get(key,default = None)
返回字典d
中key
对应的值,如果不存在,返回default
,default
可以省略,省略的时候就返回None
,也就是啥都没有,打印出来为None
,但是设定默认值之后,就会有参数返回。
d = {'dog':5,'cat':4}
print(d.get("monkey"))
d.get("monkey","undefined")
None
undefined
pop
删除元素pop用来弹出字典某个键对应的值,同时可以指定键不存在是的返回值。
d.pop(key,default = None)
删除并返回字典中key
对应的值,如果没有这个值,返回default
,default
省略时,会报错,需要设定默认返回值。
d = {'dog':5,'cat':4}
d.pop("cat")
d.pop("monkey","undefined")
del删除也是可以的:
del d["cat"]
d
{'dog': 5}
可以通过索引的方法来插入修改单个键值对,但是对于多个键值对操作的话,这种方式还是比较麻烦的,我们可以采用update的方法:
d.update(newd)
将newd
x需要修改的一个新字典中的内容更新到原字典d
中。
d = {"born":2000,"age":21}
print(d)
修改2000为20005,同时插入"sex"的值为"M"
d_modific = {"born":2005,"sex":'m'}
d.update(d_modific)
print(d)
{'born': 2005, 'age': 21, 'sex': 'm'}
in
可以用来查询字典中是否存在某个特殊的键,返回值为true
或者false
d = {'dog':5,'cat':4}
in
可以用来查询字典中是否存在某个特殊的键
'monkey' in d
False
d = {'dog': 2, 'cat': 4, 'pigs': 7}
d.keys()
['cats', 'dogs', 'pigs']
d ={'dog': 2, 'cat': 4, 'pigs': 7}
d.values()
[4, 2, 7]
d ={'dog': 2, 'cat': 4, 'pigs': 7}
d.items()
[('cats', 4), ('dogs', 2), ('pigs', 7)]
之前的元组,序列,字符串都是有序序列,每个位置和元素都一一对应,但是集合set
是一种无序的序列,和数学上的概念相同。
当集合中出现相同元素的时候,会保留一个元素,并且存入的元素不会改变。
Python中采用{}来生成集合(需要注意字典也是采用{}生成)集合中不含有相同元素,并且不会改变。
s = {2,3,4,2}
s
空集合生成:
a = set()
type(s)
set
而非:
s = {}
type(s)
dict
两个集合的交,包含两个集合的所有共有元素的集合。
可以用方法 a.intersection(b)
或者操作 a & b
实现。
a = {1,2,3,4}
b = {3,4,5,6}
a.intersection(b)
b.intersection(a)
{3, 4}
{3, 4}
a & b
b & a
{3, 4}
{3, 4}
两个集合的并,也就是两个集合所有元素的集合。
可以用方法 a.union(b)
或者操作 a | b
实现。
a = {1,2,3,4}
b = {3,4,5,6}
a.union(b)
b.union(a)
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6}
a | b
b | a
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6}
a
和 b
的差集,返回只在 a
不在 b
的元素组成的集合。
可以用方法 a.difference(b)
或者操作 a - b
实现。
a = {1,2,3,4}
b = {3,4,5,6}
a.difference(b)
b.difference(a)
{1, 2}
{5, 6}
a - b
b - a
{1, 2}
{5, 6}
a
和b
的对称差集,返回在 a
或在 b
中,但是不同时在 a
和 b
中的元素组成的集合,也就是a∪b-a∩b。
可以用方法 a.symmetric_difference(b)
或者操作 a ^ b
实现(异或操作符)。
a.symmetric_difference(b)
b.symmetric_difference(a)
{1, 2, 5, 6}
a ^ b
{1, 2, 5, 6}
要判断 b
是不是 a
的子集,可以用 b.issubset(a)
方法,或者更简单的用操作 b <= a
:
a = {1, 2, 3}
b = {1, 2}
b.issubset(a)
True
b <= a
True
跟列表的append
方法类似,可以向集合中添加单个元素。
s.add(a)
将元素a
添加到集合s
中,注意集合无序,所以是随机添加到集合的某个位置,并非添加到末尾。
t = {1, 2, 3}
t.add(5)
t
{1, 2, 3, 5}
如果添加的是已有的元素,集合石不会改变的。
方法和列表里面的extend差不多,可以一次向集合添加多个元素。
s.uodate(seq)
将seq
中的元素添加到s
z中。
t.update({5,6,7})
t
{1, 2, 3, 5, 6, 7}
s.remove(ob)
从集合s
中移除元素ob
,如果不存在会报错。
t.remove(1)
t
{2, 3, 5, 6, 7}
t.remove(10)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-31-3bc25c5e1ff4> in <module>()
----> 1 t.remove(10)
KeyError: 10
pop方法随机弹出一个元素,并不能指定删除元素,如果集合没有元素,那就会报错。
t.pop()
{3, 5, 6, 7}
s = set()
# 报错
s.pop()
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-34-9f9e06c962e6> in <module>()
1 s = set()
2 # 报错
----> 3 s.pop()
KeyError: 'pop from an empty set'
使用方法和remove相同,可以删除指定元素,而且不会返回参数,但是当集合中不存在的时候不会报错。
t = {1, 2, 3, 4, 5, 6}
t.discard(3)
{1, 2, 4, 5, 6}
t.discard(20)
t
{1, 2, 4, 5, 6}
a.difference_update(b)
就相当于a-b
对应于元组(tuple
)(参数不可改变)与列表(list
)(参数可以改变)的关系,对于集合(set
),Python提供了一种叫做不可变集合(frozen set
)的数据结构。
s = frozenset([1,2,3,'a',1])
s
frozenset({1, 2, 3, 'a'})
与集合不相同的是,不可变集合一旦创建就不能修改。
不可变集合的一个主要应用是用来作为字典的键,例如用一个字典来记录两个城市之间的距离:
flight_distance = {}
city_pair = frozenset(['Los Angeles', 'New York'])
flight_distance[city_pair] = 2498
flight_distance[frozenset(['Austin', 'Los Angeles'])] = 1233
flight_distance[frozenset(['Austin', 'New York'])] = 1515
flight_distance
可变数据类型 | 不可变数据类型 |
---|---|
list , dictionary , set , numpy array , user defined objects | integer , float , long , complex , string , tuple , frozenset |
x = [1, 2, 3]
y = x
x[1] = 100
print y
[1, 100, 3]
改变变量x
的值,变量y
的值也会随之改变,这就是和Python内部的赋值机制有关。
对于赋值的变量,可以理解为将变量y
定义成了一个指针,将它指向x
,在内存空间中,致同一块物理内存,是同一个事物,可以采用is
判断是不是指向同一事物:
x is y
True
但是对于相同的值,Python并不会对他赋予相同的内存指针。
现在来看另一段代码:
x = [500, 501, 502]
y = x
y[1] = 600
y = [700, 800]
复制ErrorOK!
x = [500, 501, 502]
Python为3个PyInt分配内存 pos1
, pos2
, pos3
(不可变),然后为列表分配一段内存 pos4
,它包含3个位置,分别指向这3个内存,最后再让变量 x
指向这个列表。
简单来说,就是创建三个储存简单值的内存,在创造一个列表,储存三个简单值的内存,然后让x
指向这个列表。
内存 | 命名空间 |
---|---|
pos1 : PyInt(500) (不可变) | |
pos2 : PyInt(501) (不可变) | |
pos3 : PyInt(502) (不可变) | |
pos4 : PyList(pos1, pos2, pos3) (可变) | x : pos4 |
y = x
并没有创建新的对象,只需要将 y
指向 pos4
即可。
内存 | 命名空间 |
---|---|
pos1 : PyInt(500) (不可变) | |
pos2 : PyInt(501) (不可变) | |
pos3 : PyInt(502) (不可变) | |
pos4 : PyList(pos1, pos2, pos3) (可变) | x : pos4 |
y : pos4 |
y[1] = 600
原来 y[1]
这个位置指向的是 pos2
,由于不能修改 pos2
的值,所以首先为 600
分配新内存 pos5
。
再把 y[1]
指向的位置修改为 pos5
。此时,由于 pos2
位置的对象已经没有用了,Python会自动调用垃圾处理机制将它回收。
内存 | 命名空间 |
---|---|
pos1 : PyInt(500) (不可变) | |
pos2 : 垃圾回收 | |
pos3 : PyInt(502) (不可变) | |
pos4 : PyList(pos1, pos5, pos3) (可变) | |
pos5 : PyInt(600) (不可变) | x : pos4 |
y : pos4 |
y = [700, 800]
首先创建这个列表,然后将变量 y
指向它。
内存 | 命名空间 |
---|---|
pos1 : PyInt(500) (不可变) | |
pos3 : PyInt(502) (不可变) | |
pos4 : PyList(pos1, pos5, pos3) (可变) | |
pos5 : PyInt(600) (不可变) | |
pos6 : PyInt(700) (不可变) | |
pos7 : PyInt(800) (不可变) | |
pos8 : PyList(pos6, pos7) (可变) | x : pos4 |
y : pos8 |
虽然都是用 if
关键词定义判断,但与C,Java等语言不同,Python不使用 {}
将 if
语句控制的区域包含起来。Python使用的是缩进方法。同时,也不需要用 ()
将判断条件括起来。
x = -0.5
if x > 0:
print ("Hey!")
print ("This isn't part of the block, and will always print.")
while <condition>:
<statesments>
Python会循环执行<statesments>
,直到<condition>
不满足为止,注意其中condition后面有一个:
。
i = 0
total = 0
while i < 1000000:
total += i
i += 1
print (total)
499999500000
plays = set(['Hamlet', 'Macbeth', 'King Lear'])
while plays:
play = plays.pop()
print ('Perform', play)
注意print函数的使用方法,中间采用,
连接:
print(var1,var2)
for <variable> in <sequence>:
<indented block of code>
for
循环会遍历完<sequence>
中所有元素为止,注意有in
和最后的:
,variable
就相当于列表里面的一个变量代表。
plays = set(['Hamlet', 'Macbeth', 'King Lear'])
for play in plays:
print ('Perform', play)
Perform King Lear
Perform Macbeth
Perform Hamlet
函数function
,通常接受输入参数,并有返回值。
def add(x, y): #注意这里有一个冒号
"""Add two numbers"""
a = x + y
return a
函数通常有一下几个特征:
def
关键词来定义一个函数。def
后面是函数的名称,括号中是函数的参数,不同的参数用 ,
隔开, def foo():
的形式是必须要有的,参数可以为空;docstring
用 """
包含的字符串,用来解释函数的用途,可省略;return
返回特定的值,如果省略,返回 None
。使用函数时,只需要将参数换成特定的值传给函数。
Python并没有限定参数的类型,因此可以使用不同的参数类型:
print add(2, 3)
print add('foo', 'bar')
5
foobar
在定义函数的时候,也可以修设置默认值:
def quad(x, a=1, b=0, c=0):
return a*x**2 + b*x + c
在输入的时候,可以省略带有默认值的参数:
print quad(2.0)
4.0
还可以修改默认值:
print quad(2.0, b=3)
10.0
如果输入的参数数目不确定,可以采用以下方法:
def add(x, *args):
total = x
for arg in args:
total += arg #将x添加到arg这个元组中
return total
这里,*args
表示参数数目不定,可以看成一个元组,把第一个参数后面的参数当作元组中的元素。
print add(1, 2, 3, 4)
print add(1, 2)
10
3
这样定义的函数不能使用关键词传入参数,要使用关键词,可以这样:
def add(x, **kwargs):
total = x
for arg, value in kwargs.items():
print "adding ", arg
total += value
return total
这里, **kwargs
表示参数数目不定,相当于一个字典,关键词和值对应于键值对。
print add(10, y=11, z=12, w=13)
adding y
adding z
adding w
46
再看这个例子,可以接收任意数目的位置参数和键值对参数:
def foo(*args, **kwargs):
print args, kwargs
foo(2, 3, x='bar', z=10)
(2, 3) {'x': 'bar', 'z': 10}
不过要按顺序传入参数,先传入位置参数 args
,在传入关键词参数 kwargs
。
Python中可以返回多个值:
from math import atan2
def to_polar(x,y):
r = (x**2 + y**2) ** 0.5
theta = atan2(y,x)
return r, theta
r, theta = to_polar(3,4)
print(r, theta)
5.0 0.927295218002
事实上,Python将返回的两个值变成了元组:
可以通过 map
的方式利用函数来生成序列:
def sqr(x):
return x ** 2
a = [2,3,4]
print map(sqr, a)
[4, 9, 16]
其用法为:
map(aFun, aSeq)
将函数 aFun
应用到序列 aSeq
上的每一个元素上,返回一个列表,不管这个序列原来是什么类型。
事实上,根据函数参数的多少,map
可以接受多组序列,将其对应的元素作为参数传入函数:
In [24]:
def add(x, y):
return x + y
a = (2,3,4)
b = [10,5,3]
print map(add,a,b)#将a和b的对应元素尽心add操作
[12, 8, 7]
写入测试文件:
%%writefile test.txt
this is a test file.
hello world!
python is good!
today is a good day.
Writing test.txt
使用 open
函数或者 file
(目前使用存在问题)函数来读文件,使用文件名的字符串作为输入参数:
f = open('test.txt')
读文件的方法:
——可以使用 read
方法来读入文件中的所有内容:
text = f.read()
print (text)
this is a test file.
hello world!
python is good!
today is a good day.
——也可以按照行读入内容,readlines
方法返回一个列表,每个元素代表文件中每一行的内容:
f = open('test.txt')
lines = =f.readlines()
print(lines)
使用完文件之后,需要将文件关闭。
f.close()
事实上,我们可以将 f
放在一个循环中,得到它每一行的内容:
f = open('test.txt')
for line in f:
print line
f.close()
this is a test file.
hello world!
python is good!
today is a good day.
我们使用 open
函数的写入模式来写文件:
f = open('myfile.txt', 'w')
f.write('hello world!')
f.close()
使用 w
模式时,如果文件不存在会被创建,我们可以查看是否真的写入成功:
print open('myfile.txt').read()
hello world!
如果文件已经存在, w
模式会覆盖之前写的所有内容:
another hello world!
除了写入模式,还有追加模式 a
,追加模式不会覆盖之前已经写入的内容,而是在之后继续写入:
f = open('myfile.txt', 'a')
f.write('... and more')
f.close()
print open('myfile.txt').read()
another hello world!... and more
写入结束之后一定要将文件关闭,否则可能出现内容没有完全写入文件中的情况。
f = open('myfile.txt','w+')
f.write('hello world!')
f.seek(6)
print(f.read())
f.close
world!
这里 f.seek(6)
移动到文件的第6个字符处,然后 f.read()
读出剩下的内容。
ipython解释器提供了很多以百分号%
开头的magic
命令,这些命令很像linux系统下的命令行命令(事实上有些是一样的)。
whos
查看当前变量空间%whos
Variable Type Data/Info
----------------------------
a int 1
b list n=3
reset
重置当前变量空间%reset -f
之后在查看变量空间
%whos
Interactive namespace is empty.
pwd
查看当前工作环境%pwd
'C:\\Users\\光明斗士'
mkdir
产生新文件夹:%mkdir demo_test
cd
改变当前工作环境%cd demo_test/
writefile
将cell中的内容写入文件:%%writefile hello_world.py
print "hello world"
Writing hello_world.py
ls
查看当前文件夹的文件:%ls
2022/08/23 16:35 <DIR> .
2022/08/23 16:35 <DIR> ..
2022/08/23 16:35 22 hello_world.py
1 ���ļ� 22 �ֽ�
2 ��Ŀ¼ 32,185,081,856 �����ֽ�
run
来运行这段代码:%run hello_world.py
hello world
这个指令只能删除文件,不能删除文件夹,并且注意一定要括号!!
import os
os.remove("hello_world.py") #单双括号都可以,但一定要有括号
%cd .. #注意是%cd(空格)..(空格)
注意里面有文件的时候不能删除,只有把里面的文件全部移除才能删除文件夹。
也就是说只能删除空文件!
%rmdir demo_test #demo_test必须是空文件
ipython 支持使用 <tab>
键自动补全命令。
Python会将所有 .py
结尾的文件认定为Python代码文件,考虑下面的脚本 ex1.py
:
%%writefile ex1.py
PI = 3.1416
def sum(lst):
tot = lst[0]
for value in lst[1:]:
tot = tot + value
return tot
w = [0, 1, 2, 3]
print sum(w), PI
可以执行它:
%run ex1.py
6 3.1416
这个脚本可以当作一个模块,可以使用import
关键词加载并执行它(这里要求ex1.py
在当前工作目录,也就是和这个工程的文件相同):
import ex1
6 3.1416
在导入时,Python会执行一遍模块中的所有内容。
ex1.py
中所有的变量都被载入了当前环境中,不过要使用
ex1.变量名
的方法来查看或者修改这些变量:
print (ex1.PI)
3.1416
还可以用
ex1.函数名
调用模块里面的函数:
print (ex1.sum([2, 3, 4]))
9
为了提高效率,Python只会载入模块一次,已经载入的模块再次载入时,Python并不会真正执行载入操作,哪怕模块的内容已经改变。
??模块和脚本的区别??
有时候我们想将一个 .py
文件既当作脚本,又能当作模块用,这个时候可以使用 __name__
这个属性。
只有当文件被当作脚本执行的时候, __name__
的值才会是 '__main__'
,所以我们可以:
%%writefile ex2.py
PI = 3.1416
def sum(lst):
""" Sum the values in a list
"""
tot = 0
for value in lst:
tot = tot + value
return tot
def add(x, y):
" Add two values."
a = x + y
return a
def test():
w = [0,1,2,3]
assert(sum(w) == 6)
print ('test passed.')
if __name__ == '__main__':
test()
Writing ex2.py
运行文件(执行脚本,此时__name__
的值才会是 '__main__'
,test会运行):
%run ex2.py
test passed.
当作模块导入, test()
不会执行:
import ex2
但是可以使用其中的变量:
ex2.PI
3.1416
使用别名,给指定函数换个名字:
import ex2 as e2
e2.PI
3.1416
可以从模块中导入变量:
from ex2 import add, PI
使用 from
后,可以直接使用 add
, PI
:
也就是从ex2
里面导入add
和PI
这两个内容。
add(2, 3)
5
或者使用 *
导入所有变量:
from ex2 import *
add(3, 4.5)
7.5
这种导入方法不是很提倡,因为如果你不确定导入的都有哪些,可能覆盖一些已有的函数。
假设我们有这样的一个文件夹:
foo/
__init__.py
bar.py
(defines func)baz.py
(defines zap)这意味着 foo 是一个包,我们可以这样导入其中的内容:
from foo.bar import func
from foo.baz import zap
bar
和 baz
都是 foo
文件夹下的 .py
文件。
导入包要求:
foo
在Python的搜索路径中__init__.py
表示 foo
是一个包,它可以是个空文件。直接在jupter(anaconda)中搜索
关于如何导入中文字府库:
再处理小说之前,我们需要先做一些准备工作。
因为涉及中文字符,所以我们使用 __future__
中 Python 3 的特性,将所有的字符串转为 unicode
。
In [1]:
from __future__ import unicode_literals
复制ErrorOK!
再来我们解决图像里中文字符显示的问题,Matplotlib虽然支持 unicode
编码,但是直接输出中文字体会出现问题。
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
%matplotlib inline
x = range(10)
plt.plot(x)
plt.title("中文")
plt.show()
会在jupter中出现如下图像(注意最上端并未显示中文两字,这就是中文加载不出来):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Itmw7dPt-1661576171055)(C:\Users\光明斗士\AppData\Roaming\Typora\typora-user-images\image-20220825225042888.png)]
出现上图的原因是它找不到合适的中文字体去显示中文,为此,我们可以去寻找一些支持中文的字体来进行设置。
Windows 7
及以上的系统中,字体位置为 C:/Windows/Fonts
,例如:
C:/Windows/Fonts/simsum.ttc
Linux
系统可以通过 fc-list
命令查看已有的字体和相应的位置,例如:
/usr/share/fonts/truetype/osx-font-family/Songti.ttc: Songti TC,宋體\-繁,宋体\-繁:style=Bold,粗體,粗体
/usr/share/fonts/truetype/osx-font-family/Devanagari Sangam MN.ttc: Devanagari Sangam MN,देवनागरी संगम एम॰एन॰:style=Bold,粗體,Fed,Fett,Puolilihava,Gras,Grassetto,ボールド,볼드체,Vet,Fet,Negrito,Жирный,बोल्ड,粗体,Negrita
/usr/share/fonts/truetype/osx-font-family/Iowan Old Style.ttc: Iowan Old Style,Iowan Old Style Black:style=Black Italic,Italic
也可以从网上直接下载字体
Yahei Consolas
的字体 YaHei.Consolas.1.11b.ttf
。找到了字体的位置,我们可以使用 matplotlib.font_manager
中的FontProperties
导入字体:
这种方式就是绝对路径,这种方式需要依赖本地文件,并不好。
font_xxx = FontProperties(fname="/usr/share/fonts/truetype/osx-font-family/Songti.ttc")
font_xxx = FontProperties(fname="C://Windows//Fonts//simsum.ttc")
为了方便,我们不使用字体的绝对路径导入,而是将需要的字体放在程序对应的文件夹下:
需要注意的是,如果错误出现提示不存在文件,先检查拼写是否出错,在检查其他格式问题!
simsum.ttc
YaHei.Consolas.1.11b.ttf
from matplotlib.font_manager import FontProperties
font_simsum = FontProperties(fname="simsun.ttc")
font_yahei_consolas = FontProperties(fname="YaHei.Consolas.1.11b.ttf")
在绘图的时候进行设置:
x = range(10)
plt.plot(x)
plt.title("中文", fontproperties=font_yahei_consolas, fontsize=14)
plt.show()
title函数的使用规则就是(标题名字,字体,大小)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8UoIcOB-1661576171056)(C:\Users\光明斗士\AppData\Roaming\Typora\typora-user-images\image-20220825232407517.png)]
Q
Python2和Python3在处理中文的时候会发生问题,之前在看爬虫教程的时候,用到的是:
response.encoding = 'utf-8' #改中文乱码方式1
img_name.encode('iso-8859-1').decode('gbk') #通用处理中文乱码的方式2
但是这回,我按照网上的流程处理之后,能显示文字了,但是文字是乱码的,还是在处理文字的时候需要观察一下问题所在。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ulg063ze-1661576171057)(C:\Users\光明斗士\AppData\Roaming\Typora\typora-user-images\image-20220826001557827.png)]
Q:
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xbf in position 2: illegal multibyte sequence
A:
在打开文本的时候encoding方式出问题,需要在打开文本的地方输入encoding = ‘utf-8’。
最终代码如下:
with open('novels/天龙八部.txt',encoding='utf-8') as f:
# 去掉结尾的换行符
data = [line.strip().encode('utf8').decode('utf8') for line in f.readlines()]
#读取大段文字
for line in data[:13]: #返回14行的列表
if line.strip():
print(line)
或者简单一点:
with open('novels/天龙八部.txt',encoding='utf-8') as f:
# 去掉结尾的换行符
data = [line.strip() for line in f.readlines()]
for line in data[:13]:
if line.strip():
print (line)
plot(x)
plt.title(“中文”)
plt.show()
会在jupter中出现如下图像(注意最上端并未显示中文两字,这就是中文加载不出来):
[外链图片转存中...(img-Itmw7dPt-1661576171055)]
出现上图的原因是它找不到合适的中文字体去显示中文,为此,我们可以去寻找一些支持中文的字体来进行设置。
`Windows 7` 及以上的系统中,字体位置为 `C:/Windows/Fonts`,例如:
- 宋体:`C:/Windows/Fonts/simsum.ttc`
`Linux` 系统可以通过 `fc-list` 命令查看已有的字体和相应的位置,例如:
- `/usr/share/fonts/truetype/osx-font-family/Songti.ttc: Songti TC,宋體\-繁,宋体\-繁:style=Bold,粗體,粗体`
- `/usr/share/fonts/truetype/osx-font-family/Devanagari Sangam MN.ttc: Devanagari Sangam MN,देवनागरी संगम एम॰एन॰:style=Bold,粗體,Fed,Fett,Puolilihava,Gras,Grassetto,ボールド,볼드체,Vet,Fet,Negrito,Жирный,बोल्ड,粗体,Negrita`
- `/usr/share/fonts/truetype/osx-font-family/Iowan Old Style.ttc: Iowan Old Style,Iowan Old Style Black:style=Black Italic,Italic`
也可以从网上直接下载字体
- 比如 `Yahei Consolas` 的字体 `YaHei.Consolas.1.11b.ttf`。
找到了字体的位置,我们可以使用 `matplotlib.font_manager` 中的`FontProperties` 导入字体:
这种方式就是绝对路径,这种方式需要依赖本地文件,并不好。
```py
font_xxx = FontProperties(fname="/usr/share/fonts/truetype/osx-font-family/Songti.ttc")
font_xxx = FontProperties(fname="C://Windows//Fonts//simsum.ttc")
为了方便,我们不使用字体的绝对路径导入,而是将需要的字体放在程序对应的文件夹下:
需要注意的是,如果错误出现提示不存在文件,先检查拼写是否出错,在检查其他格式问题!
simsum.ttc
YaHei.Consolas.1.11b.ttf
from matplotlib.font_manager import FontProperties
font_simsum = FontProperties(fname="simsun.ttc")
font_yahei_consolas = FontProperties(fname="YaHei.Consolas.1.11b.ttf")
在绘图的时候进行设置:
x = range(10)
plt.plot(x)
plt.title("中文", fontproperties=font_yahei_consolas, fontsize=14)
plt.show()
title函数的使用规则就是(标题名字,字体,大小)
[外链图片转存中…(img-u8UoIcOB-1661576171056)]
Q
Python2和Python3在处理中文的时候会发生问题,之前在看爬虫教程的时候,用到的是:
response.encoding = 'utf-8' #改中文乱码方式1
img_name.encode('iso-8859-1').decode('gbk') #通用处理中文乱码的方式2
但是这回,我按照网上的流程处理之后,能显示文字了,但是文字是乱码的,还是在处理文字的时候需要观察一下问题所在。
[外链图片转存中…(img-ulg063ze-1661576171057)]
Q:
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xbf in position 2: illegal multibyte sequence
A:
在打开文本的时候encoding方式出问题,需要在打开文本的地方输入encoding = ‘utf-8’。
最终代码如下:
with open('novels/天龙八部.txt',encoding='utf-8') as f:
# 去掉结尾的换行符
data = [line.strip().encode('utf8').decode('utf8') for line in f.readlines()]
#读取大段文字
for line in data[:13]: #返回14行的列表
if line.strip():
print(line)
或者简单一点:
with open('novels/天龙八部.txt',encoding='utf-8') as f:
# 去掉结尾的换行符
data = [line.strip() for line in f.readlines()]
for line in data[:13]:
if line.strip():
print (line)