目录

  • 1.实现一行输入多个数字,用空格隔开
  • 2.实现一行输入多个单词,用","隔开
  • 3.列表
  • 4.for循环
  • 5.切片
  • 6.二维列表
  • 7.元组
  • 8.字典
  • set容器
  • 9.嵌套
    • 字典列表——列表里嵌套字典
    • 字典列表——字典里面嵌套列表
    • 字典字典——字典中嵌套字典不就是结构体嘛struct
  • 10.input()函数
  • 11.while语句
  • 12.通过输入来填充字典
  • 13.函数
    • 函数赋值操作
    • global 和 nonlocal 的作用域
    • 位置实参
    • 关键字实参
    • 形参的默认值
    • 返回值
    • 传递列表,任何形式的实参都可以传递过来
    • 函数嵌套
  • 14.模块
    • 模块是扩展名为.py的文件
    • pizza.py文件
  • 15.类,创建和使用类
  • 16.类的继承
  • 17.导入类:
    • format()
    • f-string
    • list
    • tuple
    • dict
    • set
    • 空函数
    • 可变参数
    • 关键字参数
    • 命名关键字参数
    • 参数组合
    • 列表生成式
      • 生成器
    • 迭代器
    • 传入函数

趁着暑假花了几天的时间简单地学了一遍python的基础知识,虽然只用它的高精但是基础的还是要学一下的 选用的教材是《python编程从入门到实践》,很好的一本书,简单易懂python是真的简单,C++天下第一

python的优点在于自带高精,函数库非常丰富。简单易懂,不像C++必须从主函数开始调用,python任何地方都算,没有主函数main(),随意写,遍地开花

1.实现一行输入多个数字,用空格隔开

a,b,c,d=map(int,input().split(' '))#split()默认以空格隔开
print(a,b,c,d)
print(type(a))

输入:

1 2 3 4

输出:

1 2 3 4
<class 'int'>

2.实现一行输入多个单词,用","隔开

str1,str2,str3=map(str,input().split(','))
print(str1,str2,str3)
print(type(str1))

输入:

aaa,bbb,ccc

输出:

aaa bbb ccc
<class 'str'>

3.列表

(类似数组—什么都能同时存的数组)


a=[]
s='11'
#强制转换
s=int(s)
print(s)
#列表插入元素
a.insert(0,1)
a.insert(1,2)
a.insert(3,0)
print(a)
#列表翻转
a.reverse()
print(a)
#列表长度
print(len(a))

4.for循环

在同一行缩进里相当于是一个大括号里同时执行

for ans in a:print(ans)print(a)
#range函数遍历数,相当于for(int i=1;i<10;i++)i相当于下面的val
for val in range(1,10):print(val)
#10到90(从0开始100结束不包括100(for(int i=0;i<100;i+=10)cout<<i<<endl;)
susm=list(range(0,100,10))#将数字列表转换成列表list直接赋值给新列表
for tmp in susm:print(tmp)
susm=[]
for t in range(1,11):susm.append(t**2)
print(susm)
#min函数
print(min(susm))
#max函数
print(max(susm))
#sum函数求和
print(sum(susm))

5.切片

qq=[tt*2+1 for tt in range(1,11)]
print(qq)
print(qq)
#切片
print(qq[-3:])
#从头到尾
my_qq=qq[:]
#列表里什么类型都可以放
my_qq.append('qq')
print(my_qq)
for t in qq:if  t==5:print("ok")elif t!=9and t<=13:#&&print("ok")elif t==3or t==21:#||print("ok")else :print(t)

6.二维列表


lists=[[]for i in range(3)]
lists[0].append(3)
lists[1].append(4)
lists[2].append(5)
print(lists)
#用python实现二维数组
myList = [([0] * 3) for i in range(4)]
myList[0][1]=1
myList[1][1]=666
print(myList)

7.元组

就是const 数组,不能修改元素,但是可以直接给这个元组的变量再赋值,重新定义这个元组以达到修改的目的


yuanzu= (100, 200)
for tmp in yuanzu:print(tmp)
if 19 in my_qq:print("yes")
if 666666 not in my_qq:print("666666 is not in my_qq")
tt=[]
#判断列表是否为空
if tt:print("非空")
else:print("空的")

8.字典

类似C++中的map<string,string>


my_house={'color':'blue','value':10000000.5}
#可以是字符串也可以是int double(键必须加''引号)python中''与""一样my_house['color']='red'
#可以直接赋值print(my_house['color'])
print(my_house['value'])
money=my_house['value']print('I have'+' '+str(money)+' !')#字典是动态的结构,可以随时赋值my_house['location']='china'
print(my_house)#注意字典中键—值对的排列顺序与添加顺序不一定相同,python只关心键与值之间的关联关系
my_house['value']+=1003#和C++差不多也可以+=
print(my_house['value'])#删除键—值对
del my_house['color']
print(my_house)#永远删除
favorite_languages= {'meng':'c++','liu':'java',#注意每个键值对中间都有冒号:后面都有逗号,'yang':'python','geng':'c++'
}
print(favorite_languages)
s=favorite_languages['meng']+' 天下第一 !'
print(s)#遍历字典的全部键值对
for key,val in favorite_languages.items():print("key:"+key)print("value:"+val)#遍历字典的全部键
for k in favorite_languages.keys():print("key:"+k)
frinds=['liu','yang']#遍历字典的全部键,此写法与上面的效果一模一样
for k in favorite_languages:print(k)if k in frinds:print("oh my god  "+k+"  !!您tql!!!")#xxx.keys()返回的是一个列表,所以可以有下面的操作
if 'xishen' not in favorite_languages.keys():print("xishen tql")#sorted()排序按字典序排序
for name in sorted(favorite_languages.keys()):print(name.title() + "  thank you !!% % %")#遍历字典中的所有的值
for val in favorite_languages.values():print(val)

set容器

类似C++里的set,自动去重
set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

for val in set(favorite_languages.values()):print(val)

9.嵌套

字典列表——列表里嵌套字典

aliens = []
for i in range(0,30):new_aliens={'color':'green','point':5,'speed':'slow'}aliens.append(new_aliens)if i<3:aliens[i]['color']='yellow'aliens[i]['point']=10aliens[i]['speed']='medium'#跟c++中的map差不多支持直接下标访问aliens[i]['extra']='money+10'#也可以直接添加新键值对
for alien in aliens[0:5]:print(alien)
print("---------------------------------------")

字典列表——字典里面嵌套列表

pizza={'crust':'thick','toppings':['mushrooms','bacon','extra cheese'],
}
for topping in pizza['toppings']:print("\t"+topping)
language={'meng':['c++','python'],'yang':['c++'],
}
for name,langu in language.items():print('\n'+name.title()+"'s favorite language are")for i in langu:print('\t',i.title())

字典字典——字典中嵌套字典不就是结构体嘛struct


users = {'dalao' : {'first' : 'yang','last' : 'niubi','location':'hubei',},'caiji':{'first':'meng','last':'juruo','location':'henan',},
}
for username,user_info in users.items():print("\nUsername: "+username)full_name=user_info['first']+" "+user_info['last']location=user_info['location']print("\tFull name: "+full_name.title())print("\tLocation: "+location.title())

10.input()函数


tmp="hello,my friend"
tmp+="\nplease say something,and i will repeat it back to you : "
message=input(tmp)#可以直接在input()里加一些东西作为提示词
print(message)

11.while语句


cnt=0
while cnt<=3 :print(cnt)cnt+=1 #python 里没有cnt++
#break的使用
while cnt <=100:cnt+=1if cnt%2==0:continueprint(cnt)if cnt ==25:break
users=['meng','long','yang','long']
confirmed_users=[]
while users:#while(users)只要users内有元素就不停止current_user=users.pop()print(current_user)confirmed_users.append(current_user)
for i in confirmed_users:print("confirmed user: "+i)
users = ['meng', 'long', 'yang', 'long']
print(users)
while 'long' in users:users.remove('long')
print(users)

12.通过输入来填充字典


date={}
flag=True
while flag:name=input("\nyour name:")language=input("your favorite")date[name]=languagerepeat=input("do you want to continue?(yes/no)")if repeat == 'no':flag=False
print("------------------")
for name,language in date.items():print(name+" like "+language+".")

13.函数

跟C++一样必须先定义函数再调用,同一个函数名可以重复定义,并及时使用,因为后一个定义的会覆盖前一个,并不会像函数重载那样自动识别

函数赋值操作

对于函数 f()a=f 型属于将变量指向函数。

举个例子:

>>> f = abs
>>> f(-10)
10

说明变量f现在已经指向了 abs 函数本身。直接调用 abs() 函数和调用变量 f() 完全相同。

再举个例子:

def maker(N): def action(X):  return X ** N return action

这个嵌套函数的外层返回值为内层函数的函数名,注意没有括号,这里有无括号是有很大区别的。此时调用外部函数:

f = maker(2)

f 指向了 action 函数

>>> f(3)
9

证明 f 和 action 函数是一样的。

def hi(name="yasoob"):return "hi " + name
print(hi())
# output: 'hi yasoob'
# 我们可以将一个函数赋值给一个变量,比如
greet = hi
# 我们这⾥没有在使用小括号,因为我们并不是在调用hi函数
# ⽽是在将它放在greet变量里。我们尝试运行下这个
print(greet())
# output: 'hi yasoob'
# 如果我们删掉旧的hi函数
del hi
print(hi())
#outputs: NameError
print(greet())
#outputs: 'hi yasoob'

global 和 nonlocal 的作用域

❑❑❑ global

在外面的默认为全局变量,但是若想在函数内修改全局变量需要在函数内声明一次这个全局变量

cnt = 0
def counter():count = 0global cntcnt += 1
counter()
print(cnt)
1

如果不涉及修改操作,那么直接使用是正常的。

❑❑❑ nonlocal

nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。

def counter():count = 0 def inc():nonlocal count count += 1print("ok")return countreturn inc
fun = counter()# 只调用了一次counter函数
print(fun())# 调用三次inc函数
print(fun())
print(fun())
ok
1
ok
2
ok
3

位置实参

必须严格按照形参位置来安排实参位置

def greet_user(name):"""显示简单的问候语"""print("hello ! "+name.title()+' ! ')
greet_user("meng")
"""
多行注释==/* */
1
"""

关键字实参

def tql(name,score):score+=50print(name+str(score)+'分'+" tql"+ ' AK全场 !' )
tql(score=50,name='dongge')#关键字实参,可以不按顺序
def tql():print("ok")
tql()

形参的默认值


def pet(pet_name,species='dog'):print("my "+species+"'s name is "+pet_name)
pet('wangcai')#位置实参,按顺序
pet('wangwang','cat')
pet(pet_name='ritian')
pet(species='bear',pet_name='miaomiao')

返回值


#可选实参
def total_name(first_name,last_name,middle_name=''):#令这个可选形参为空字符串并放到最后if middle_name:#字符串可以直接if判空full_name = first_name + ' ' + middle_name + ' ' + last_nameelse:full_name=first_name+' '+last_namereturn full_name
name=total_name('meng','yu')
print(name)
name=total_name('meng','yu','fan')
print(name)
#返回字典
def build_person(first_name,last_name,age=''):#必须有冒号! ':'person={'first name':first_name,'last name':last_name}if age:person['age']=agereturn person
caiji=build_person('meng','fanyu',age=20)
print(caiji)
while True:print("\nPlease tell me your name")print("(enter 'q' at any time to quit)")f_name=input("first name: ")if f_name=='q':breakl_name=input("last name: ")if l_name=='q':breakformatted_name=total_name(f_name,l_name)print("hello ,"+formatted_name+" !")

传递列表,任何形式的实参都可以传递过来

def name(names):print(names)
namess={'123':11,'meng':666}
name(namess)
base_name=[]
def greet_users(names):while names:i=names.pop()#形参可以直接改变实参print(i)base_name.append(i)
name=['meng','wang','yang']
greet_users(name[:])#如果用(name)会被改变,但是加上[:]之后,就不会被改变
print(base_name)
print(name)

函数嵌套

14.模块

将函数存到模块中

模块是扩展名为.py的文件

def makes(size,*toppings):print("meka a "+str(size)+" -inch pizza")print("pizza with following toppings")for i in toppings:print("-"+i)

pizza.py文件

#导入模块:
import pizza
#导入具体的函数:
from pizza import makes
#导入具体函数并用as来指定别名:
from pizza import makes as mp
mp(16,'musgroom')
#用as给模块指定别名
import pizza as p
#导入模块的所有函数
#星号*运算符可以让python导入模块中的所有函数
from pizza import *

15.类,创建和使用类

class Dog():#方法,方法_init_()是一个特殊的方法,每当你根据Dog来创建类的时候python就会自动调用运行它#类中每个属性都必须初始化def __init__(self,name,age):"""初始化属性name 和 age"""self.name=nameself.age=ageself.money=0#给属性指定默认值#可以设置默认值,这样就不用在形参列表里传入这个属性即可直接调用,如上面的那个moneydef sit(self):"""模仿小狗被命令蹲下的操作"""print(self.name.title()+"is now sitting ")def roll(self):"""模仿小狗被命令时打滚"""print(self.name.title()+"rolled over!")def make_a_profit(self,up,down):if down>0:print("我怎么赔钱了")self.money-=downelse :print("我赚钱啦")self.money+=updef feed_dog(self):print("ok,my dog is fulled")
my_dog=Dog('喵喵',6)
your_dog=Dog('旺财',1)
print("my dog 's name is " +my_dog.name.title()+".")
print("my dog is "+str(my_dog.age)+"years old .")
my_dog.sit()
my_dog.roll()
my_dog.feed_dog()
your_dog.sit()
print("your money:"+str(your_dog.money))
#修改属性的值:
#1.直接修改:
my_dog.money=1000000000
print("my money : "+str(my_dog.money)+"人民币")
#2.通过方法(函数)修改属性里的值
#在类里编写一个函数即可,然后调用
my_dog.make_a_profit(666666,0)
print("my money : "+str(my_dog.money)+"人民币")

16.类的继承


#一个类继承另一个类时,它将自动获得了另一个类的全部属性和方法(python里的方法,其实就是成员函数)
#原有的类被称为父类,而新类被称为子类,子类继承了父类的所有发属性和方法,并且可以定义自己的属性和方法
class robot_dog(Dog):#需要用super函数来帮助子类获得父类的属性和方法def __init__(self,name,age):super(robot_dog, self).__init__(name,age)#这个是继承用的,新属性不用在这儿写,写到下面就好self.electric_quantity=100#类的属性也可以用别的类来初始化例如:self.battery=Battery()(#具体的Battery类懒得写了)#这样初始化的属性,这个类也可以用Battery类的方法#添加新方法def describe_battery(self):print("my robot dog's battery is "+str(self.electric_quantity)+"% . ")#改写父类的方法def feed_dog(self):print("electric dog does not need to feed !")my_robot_dog=robot_dog('小蜗',100)
#子类获得之后可以直接调用父类的方法
my_robot_dog.make_a_profit(666666666666,0)
print(str(my_robot_dog.money))
my_robot_dog.describe_battery()
my_robot_dog.feed_dog()

17.导入类:

from MY_Dog import Dog#MY_Dog 是文件的拓展名MY_Dog.py
#其实就是把一个模块里放入一些类(一个或多个),然后正常地调用就好
from MY_Dog import Dog , robot_dog
import MY_Dog
from MY_Dog import *
#在一个模板中导入另一个模板#MY_Dog.py和Robot_Dog.py
from MY_Dog import Dog
from Robot_Dog import robot_dog
#从collections中导入类OrderedDict,调用它,即创建了一个记录了键值对的字典
from collections import OrderedDict
i=OrderedDict()
i['meng']='C++'
i['yang']='python'
i['wang']='C#'
for name,language in i.items():print(name.title()+"'s favorite language is "+language.title()+".")

更多python请看廖雪峰Python3教程.
ψ(`∇´)ψ


test code

import math
import numpy as npa = 10
print(type(a))
print(a)
p = ['one', 10, 'ju', 3.14, 1000, 233, "string"]
print(p[1 : 5])
print(p)
q = p[1 : 3]
print(p + q)
print(q * 2)
q.append(666)
print(q)
del q[0]
print(q)
del(q[1])
print(q)
print(666 in q)
print('ju' in q)
q.append(666)
q.append(666)
print(q)
print(q.count(666))
print(len(q))
#ptuple = const list
pTuple = ()
print(pTuple)
pTuple = ('abc')
print(pTuple)
pTuple = ('abc',)
print(pTuple)
qTuple = ('abc', 11)
print(pTuple + qTuple)
print(pTuple * 2)
len(pTuple + qTuple)
print(11 in qTuple)
pDict = {}
pDict['name'] = 'gao'
pDict['age'] = 17
pDict['sex'] = 'woman'
print(pDict.keys())
print(pDict.values())
qDict = {}
qDict['val'] = 100
del qDict['val']
print(qDict)
print(len(qDict))
a = 200
b = 100
a += b
if a != b :print("YES")
q = [1, 2, 3]
p = q
print(p is q)
t = q[ : ]
if t == q :print('yes')
if t is q:print('yes')
else :print('no')
for it in p:print(it)
n = 3
cnt = 1
sum = 0
while cnt <= n:print("yes")sum += cntcnt += 1
print("1 到 %d 之和为: %d" % (n, sum))
sum = 0
def sum_list(x):sum = 0for it in x:sum += itreturn sum
print(sum_list(p))
print(max(p))
sigma = lambda x: 1.0 / (1.0 + math.exp(-x))
print(sigma(0))
dist = lambda x,y: math.sqrt(x * x + y * y)
print(dist(3, 4))
class human:def __init__(self, name):self.name=  nameprint("初始化成功啦")def eat(self):print(self.name + " 要吃东西啦^q^")def sleep(self):print(self.name + ' 要睡觉觉啦^q^')
gf = human('xiao gao')
gf.eat()
gf.sleep()
array1 = np.array([1.0, 2.0, 3.0])
print(array1[0:2])
array2 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(array2[1, 1])
array3 = array2[1:, 1:3]
print(array3)
array3[0, 0] = 666
print(array2[1, 1])# 相当于array是一个指针 / 引用变量
array1 = np.zeros((3, 3))
print(array1)
array2 = np.full((2, 2), 5)
array3 = np.full((2, 2), 1)
array4 = np.ones((2, 2))
print(array3)
print(array4)
array5 = np.random.random((2, 2))
print(array5)
array1 = np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]])
for it in array1:print(it)
array2 = array1.flatten()#摊平了属于是,多维数组转换为一维数组
print(array1 > 5)
print(array1[array1 > 5])
a = np.array([[1.0, 2.0],[3.0, 4.0]])
b = np.array([[5.0, 6.0],[7.0, 8.0]])
print("-----------")
print(a + b)
for i in range(0, 2):for j in range(0, 2):print(a[i][j] + b[i][j])
print(a - b)
print(a * b)
print(a / b)
print(a.dot(b))
print(np.dot(a, b))
print('----------')
print(a)
print(a.T)
#广播 broadcasting
#秩可以不同,长度要相同
a = np.array([[5, 3],[1, 6]])
b = np.array([2, 7])
c = np.array([[2, 7],[2, 7]])
x = 10
print(a * 10)#数组与标量进行乘法
print(a * b)#形状不同的数组乘法
print(a * c)#形状相同的数组乘法

len()函数计算的是str的字符数,如果换成byteslen()函数就计算字节数

为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

常见的占位符有:

占位符 替换内容
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
print('%2d-%02d' % (3, 1))
print('%.3f' % 3.1415926)
 3-01
3.142

转义,用%%来表示一个%

>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'

format()

另一种格式化字符串的方法是使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}{1}……,不过这种方式写起来比%要麻烦得多:

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

f-string

最后一种格式化字符串的方法是使用以f开头的字符串,称之为f-string,它和普通字符串不同之处在于,字符串如果包含{xxx},就会以对应的变量替换:

>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62

上述代码中,{r}被变量r的值替换,{s:.2f}被变量s的值替换,并且:后面的.2f指定了格式化参数(即保留两位小数),因此,{s:.2f}的替换结果是19.62

list

len()函数可以获得list元素的个数:

list是一个可变的有序表,所以,可以往list中追加元素到末尾:

>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']

也可以把元素插入到指定的位置,比如索引号为1的位置:

>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']

要删除list末尾的元素,用pop()方法:

>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']

要删除指定位置的元素,用pop(i)方法,其中i是索引位置:

>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']

tuple

当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:

>>> t = (1, 2)
>>> t
(1, 2)

如果要定义一个空的tuple,可以写成()

>>> t = ()
>>> t
()

但是,要定义一个只有1个元素的tuple,如果你这么定义:

>>> t = (1)
>>> t
1

定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1

所以,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:

>>> t = (1,)
>>> t
(1,)

“可变的”tuple:

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

tuple里的list地址不能变,lsit里的内容可以变,满足tuple不可变

dict

通过in判断key是否存在:

>>> 'Thomas' in d
False

二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:

>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

注意:返回None的时候Python的交互环境不显示结果。

要删除一个key,用pop(key)方法,对应的value也会从dict中删除:

>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

dict内部存放的顺序和key放入的顺序是没有关系的。

dict的key必须是不可变对象

set

创建一个set,需要提供一个list作为输入集合:

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

注意,传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。。

通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果

通过remove(key)方法可以删除元素:

>>> s.remove(4)
>>> s
{1, 2, 3}

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

str是不变对象,而list是可变对象。

>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'

a是变量,而'abc'才是字符串对象

空函数

如果想定义一个什么事也不做的空函数,可以用pass语句:

def nop():pass

Python的函数返回多值其实就是返回一个tuple

>>> def fun(x, a = 2, b = 3):print(x, a, b)
>>> fun(10, b = 0)
10 2 0

默认参数

先定义一个函数,传入一个list,添加一个END再返回:

def add_end(L=[]):L.append('END')return L

当你正常调用时,结果似乎不错:

>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']

当你使用默认参数调用时,一开始结果也是对的:

>>> add_end()
['END']

但是,再次调用add_end()时,结果就不对了:

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了'END'后的list。

原因解释如下:

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

定义默认参数要牢记一点:默认参数必须指向不变对象!

要修改上面的例子,我们可以用None这个不变对象来实现:

def add_end(L=None):if L is None:L = []L.append('END')return L

现在,无论调用多少次,都不会有问题:

>>> add_end()
['END']
>>> add_end()
['END']

可变参数

在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。

要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:

def calc(numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum

但是调用的时候,需要先组装出一个list或tuple:

>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84

如果利用可变参数,调用函数的方式可以简化成这样:

>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84

所以,我们把函数的参数改为可变参数:

def calc(*numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum

定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:

>>> calc(1, 2)
5
>>> calc()
0

如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14

这种写法当然是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:

>>> nums = [1, 2, 3]
>>> calc(*nums)
14

*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。

关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:

def person(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw)

函数person除了必选参数nameage外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:

>>> person('Michael', 30)
name: Michael age: 30 other: {}

也可以传入任意个数的关键字参数:

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到nameage这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。

和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

当然,上面复杂的调用可以用简化的写法:

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra

命名关键字参数

对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。

仍以person()函数为例,我们希望检查是否有cityjob参数:

def person(name, age, **kw):if 'city' in kw:# 有city参数passif 'job' in kw:# 有job参数passprint('name:', name, 'age:', age, 'other:', kw)

但是调用者仍可以传入不受限制的关键字参数:

>>> person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)

如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收cityjob作为关键字参数。这种方式定义的函数如下:

def person(name, age, *, city, job):print(name, age, city, job)

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数。

调用方式如下:

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:

def person(name, age, *args, city, job):print(name, age, args, city, job)

命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:

>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'

由于调用时缺少参数名cityjob,Python解释器把前两个参数视为位置参数,后两个参数传给*args,但缺少命名关键字参数导致报错。

命名关键字参数可以有缺省值,从而简化调用:

def person(name, age, *, city='Beijing', job):print(name, age, city, job)

由于命名关键字参数city具有默认值,调用时,可不传入city参数:

>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer

使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数:

def person(name, age, city, job):# 缺少 *,city和job被视为位置参数pass

参数组合

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

比如定义一个函数,包含上述若干种参数:

def f1(a, b, c=0, *args, **kw):print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)def f2(a, b, c=0, *, d, **kw):print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。

>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}

最神奇的是通过一个tuple和dict,你也可以调用上述函数:

>>> args = (1, 2, 3, 4)
>>> kw = {'d': 99, 'x': '#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}

所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:

>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)

字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:

>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()

如何判断一个对象是可迭代对象呢?方法是通过collections.abc模块的Iterable类型判断:

>>> from collections.abc import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C
>>> for i, x in enumerate([(1, 1), (2, 2), (3, 3)]):
...      print(i, x[0], x[1])
...
0 1 1
1 2 2
2 3 3

上面的for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:

>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print(x, y)
...
1 1
2 4
3 9

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11))

>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

要生成[1x1, 2x2, 3x3, ..., 10x10]

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

or循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
>>> [a + b + c for a in 'ABC' for b in 'asf' for c in '124']
['Aa1', 'Aa2', 'Aa4', 'As1', 'As2', 'As4', 'Af1', 'Af2', 'Af4', 'Ba1', 'Ba2', 'Ba4', 'Bs1', 'Bs2', 'Bs4', 'Bf1', 'Bf2', 'Bf4', 'Ca1', 'Ca2', 'Ca4', 'Cs1', 'Cs2', 'Cs4', 'Cf1', 'Cf2', 'Cf4']
>>> import os
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']

for循环其实可以同时使用两个甚至多个变量,比如dictitems()可以同时迭代key和value:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k, v in d.items():
...     print(k, '=', v)
...
y = B
x = A
z = C

因此,列表生成式也可以使用两个变量来生成list:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

if写在for前面必须加else,否则报错:

>>> [x if x % 2 == 0 for x in range(1, 11)]File "<stdin>", line 1[x if x % 2 == 0 for x in range(1, 11)]^
SyntaxError: invalid syntax

这是因为for前面的部分是一个表达式,它必须根据x计算出一个结果。因此,考察表达式:x if x % 2 == 0,它无法根据x计算出结果,因为缺少else,必须加上else

>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

上述for前面的表达式x if x % 2 == 0 else -x才能根据x计算出确定的结果。

可见,在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else

生成器

如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
StopIteration

正确的方法是使用for循环,因为generator也是可迭代对象:

>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
...
0
1
4
9
16
25
36
49
64
81

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

例如函数生成斐波那契额数列:

def fib(max):n, a, b = 0, 0, 1while n < max:print(b)a, b = b, a + bn = n + 1return 'done'

上面是普通的函数,和generator仅一步之遥。要把fib函数变成generator函数,只需要把print(b)改为yield b就可以了:

def fib(max):n, a, b = 0, 0, 1while n < max:yield ba, b = b, a + bn = n + 1return 'done'

这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:

>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

generator函数和普通函数的执行流程不一样。普通函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

举个简单的例子,定义一个generator函数,依次返回数字1,3,5:

def odd():print('step 1')yield 1print('step 2')yield(3)print('step 3')yield(5)

调用该generator函数时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:

>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
StopIteration

可以看到,odd不是普通函数,而是generator函数,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错。

请务必注意:调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。

有的童鞋会发现这样调用next()每次都返回1:

>>> next(odd())
step 1
1
>>> next(odd())
step 1
1
>>> next(odd())
step 1
1

原因在于odd()会创建一个新的generator对象,上述代码实际上创建了3个完全独立的generator,对3个generator分别调用next()当然每个都会返回第一个值。

正确的写法是创建一个generator对象,然后不断对这一个generator对象调用next()

>>> g = odd()
>>> next(g)
step 1
1
>>> next(g)
step 2
3
>>> next(g)
step 3
5

回到fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

同样的,把函数改成generator函数后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

>>> for n in fib(6):
...     print(n)
...
1
1
2
3
5
8

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

迭代器

可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

为什么listdictstr等数据类型不是Iterator

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

Python的for循环本质上就是通过不断调用next()函数实现的,例如:

for x in [1, 2, 3, 4, 5]:pass

实际上完全等价于:

# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:try:# 获得下一个值:x = next(it)except StopIteration:# 遇到StopIteration就退出循环break

传入函数

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

一个最简单的高阶函数:

def add(x, y, f):return f(x) + f(y)

当我们调用add(-5, 6, abs)时,参数xyf分别接收-56abs,根据函数定义,我们可以推导计算过程为:

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

《Python基础知识全家桶》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. PAT甲级1063 Set Similarity:[C++题解]哈希表、去重
  2. Python和OpenCV环境配置
  3. Java黑皮书课后题第7章:**7.18(冒泡排序)使用冒泡排序算法编写一个排序方法。编写一个测试程序,读取10个double型的值,调用这个方法,然后显示排序好的数字
  4. java外围设计_Java 编程(23 种设计模式)
  5. Vue UI 框架对比 element VS iview
  6. python string与list互转
  7. emlog过滤html,Emlog 搜索优化 标题 + 全文搜索
  8. 从控制台读取password - C#
  9. windows vs编译环境 python_Python虚拟环境使用(Windows)
  10. 基于Matlab----MSK调制与解调
  11. Docker逐渐火起来了,收集了一些这方面的书
  12. 汉诺塔 --- 递归的经典运用
  13. 摄像头视频直播方案比较之方案一:萤石云
  14. java登录界面的实现(任何小白都可轻松实现)
  15. 计算机内存不足提示栻框,【计算机】CIMS概论6.ppt
  16. 关键词抽取——结巴分词
  17. 如何使用CANoe和CANalyzer中的Diagnostics/ISO TP
  18. 使用echarts生成海友网企业全国分布地图
  19. 国家标准GB7713-87
  20. Studio3t 过期激活办法/以及重新设置使用日期的脚本不可用解决办法/Studio 3T无限激活原创

热门文章

  1. 基于三维卷积神经网络的RGB-D显著目标检测
  2. “看墙之外” ——遮挡下的人体姿态估计
  3. hadoop思维导图
  4. 2019年2月26日 Unique Email Addresses、To Lower Case、Encode and Decode TinyURL
  5. mongodb 安装时错误
  6. CactiEz 无法登陆 、重启不画图处理
  7. 怎么申请微信支付接口
  8. unittest 框架学习
  9. 【Scala-spark.mlib】稠密矩阵和稀疏矩阵的创建及操作
  10. 设置静态固定ip地址