本篇文章为大家带来Python中的基础编程方法和技巧。
连等赋值
Python允许采用连等赋值来同时赋值多个变量
e=1
a=b=c=d=e
print(a)
# 1
print(b)
# 1
print(c)
# 1
print(d)
# 1
交换变量
其他语言中,交换变量通常这样写(以C++为例):
#include
intmain()
{
inta=1;
intb=2;
inttemp=a;
a=b;
b=temp;
printf("a: %d, b: %d\n",a,b);
return;
}
编译运行结果是:
a: 2, b: 1
而在Python中,可以这样来交换变量:
a=1
b=2
a,b=b,a
print(a)
# 2
print(b)
# 1
三元运算符
在其他语言中,三元运算符通常是这样的结构:
// C
#include
intmain()
{
inta=1;
intb=a>=1?2:3;
return;
}
运行结果是当,,否则,等价于:
// C
#include
intmain()
{
inta=1;
intb=;
if(a>=1)
{
b=2;
}
else
{
b=3;
}
return;
}
Python并不支持三元运算符,但是有语法糖支持三元操作,请看:
a=1
b=2ifa==1else3
print(b)
# 2
条件判断为,则等于前面的值,否则等于后面的值,这样便实现了三元操作。
索引与列表与遍历
1
enumerate
在系列的第一篇中(→
传送门
)提到可以利用直接遍历一个列表的值。但是,某些时候确实还需要获取到列表的索引,这时候该怎么做呢?利用:
a= [xforxin'hello']
print(a)
# ['h', 'e', 'l', 'l', 'o']
forind,valinenumerate(a):
print('{}: {}'.format(ind,val))
# 0: h
# 1: e
# 2: l
# 3: l
# 4: o
本质上是一个迭代器(迭代器是什么?→传送门),因而你可以用来访问元素:
a_enum=enumerate(a)
a_enum.__next__()
# (0, 'h')
print(check_iterator(a_enum))
# True
2
zip
另外一些情况中,可能希望同时遍历多个列表,该怎么做呢?利用:
a= [xforxin'hello']
b= [xforxinrange(5)]
c= [ord(x)forxina]
forvalinzip(a,b,c):
print(val)
# ('h', 0, 104)
# ('e', 1, 101)
# ('l', 2, 108)
# ('l', 3, 108)
# ('o', 4, 111)
按顺序将几个可迭代对象的元素聚合到元组中,这样,在迭代时就可以一次性迭代多个列表:
fora_el,b_el,c_elinzip(a,b,c):
print('{}, {}, {}'.format(
a_el,
b_el,
c_el
))
# h, 0, 104
# e, 1, 101
# l, 2, 108
# l, 3, 108
# o, 4, 111
所以,当你希望实现将两个可迭代对象分别作为一个字典的键值来生成这个字典时,是非常好的选择:
a= [xforxin'dict']
b= [xforxinrange(4)]
c=dict(zip(a,b))
print(c)
# {'c': 2, 'd': 0, 't': 3, 'i': 1}
如果可迭代对象长度不一致怎么办?只保留到最短的一个对象的长度:
a= [xforxinrange(2)]
b= [xforxinrange(3)]
c= [xforxinrange(5)]
forvalinzip(a,b,c):
print(val)
# (0, 0, 0)
# (1, 1, 1)
想要按最长的对象保留,需要使用标准库中的:
fromitertoolsimportzip_longest
forvalinzip_longest(a,b,c,fillvalue=None):
print(val)
# (0, 0, 0)
# (1, 1, 1)
# (None, 2, 2)
# (None, None, 3)
# (None, None, 4)
也是迭代器:
abc_zip=zip(a,b,c)
print(next(abc_zip))
# (0, 0, 0)
print(check_iterator(abc_zip))
# True
还有另一个作用,可以将一些组合按索引拆分成独立的部分:
l= [(1,4), (2,5), (3,6)]
a,b=zip(*l)
print(a)
# (1, 2, 3)
print(b)
# (4, 5, 6)
(还记得星号表达式吗,→传送门)现在看一个例子,利用模拟矩阵转置。我们利用嵌套列表来模拟矩阵:
fromrandomimportrandint
mat= [
[randint(x,y)forxinrange(3)]
foryinrange(3)
]
print(mat)
# [[7, 5, 10], [9, 8, 7], [3, 7, 2]]
t_mat=zip(*mat)
print(list(t_mat))
# [(7, 9, 3), (5, 8, 7), (10, 7, 2)]
有人说列表变成了元组了,希望还使用列表,可以利用列表推导式(→传送门)做一点修改:
t_mat= [list(x)forxinzip(*mat)]
print(t_mat)
# [[7, 9, 3], [5, 8, 7], [10, 7, 2]]
帮助文档
在编(ban)程(zhuan)过程中,很多时候很难记住函数的参数都有哪些。除了查询文档外,你还可以利用函数直接查看函数的帮助信息:
>>>help(zip)
Helponclasszipinmodulebuiltins:
classzip(object)
|zip(iter1[,iter2[...]])-->zipobject
|
|Returnazipobjectwhose.__next__()methodreturnsatuplewhere
|thei-thelementcomesfromthei-thiterableargument.The.__next__()
|methodcontinuesuntiltheshortestiterableintheargumentsequence
|isexhaustedandthenitraisesStopIteration.
...
这里仅贴出了前几行。你也可以为你自己的函数或类增加这样的文档:
defadd(a,b):
'''
Util: add
Params:
@ a: object
@ b: same type with a
Return:
% a plus b
'''
returna+b
help(add)
Helponfunctionaddinmodule__main__:
add(a,b)
Util:add
Params:
@a:object
@b:sametypewitha
Return:
%aplusb
小例子
生成斐波那契数列:斐波那契数列是指这样一个数列:
1,1,2,3,5,8,13,21,34, ...
其递归定义是这样的:
F(1) = 1
F(2) = 1
F(n) = F(n - 1) + F(n - 2)
它是无限长的数列。下面我们简单实现一个小程序,来获取一个斐波那契数列,并求其中小于的元素中偶数(prime)的和。首先来判断一下是否是质数:传统的思路,可能你会写出这样的代码来产生斐波那契数列,利用循环,按照上述公式计算下一个值,存到列表里:
deffibonacci(n):
fib= [1,1]
ind=2
whileTrue:
temp=fib[ind-2]+fib[ind-1]
iftemp>n:
break
fib.append(temp)
ind+=1
returnfib
然后计算偶数和:
defeven_sum(n):
fib=fibonacci(n)
s=# sum
foriinfib:
ifnot(i%2):
s+=i
returns
结合上篇文章的迭代器,加上本篇文章的一些内容,我们来完成一个更加Pythonic的版本:来看一下结果:
N=10000000
# 列表法
print(even_sum(N))
# 82790070
# 迭代器法
print(even_sum(N))
# 82790070
迭代器能够节约大量的内存(从始至终只用了两个变量)。此外,这里利用了元素交换巧妙得完成了斐波那契相加的操作。友情链接: https://vonalex.github.io/
欢迎关注 它不只是Python
领取专属 10元无门槛券
私享最新 技术干货