x = 4
y = 3
print((x > y) - (x < y))
import math
x = -3.1415926
print(math.modf(x))
var1 = 'Hello World!'
print(var1[0], var1[1], var1[2], var1[3], var1[4], var1[5], var1[6])
print(var1[1:7])
例如:`print('a' * 3)`表示输出三个a
相对于字符串hello
[] 通过索引获取字符串中字符 a[1] 输出结果 e
[ : ] 截取字符串中的一部分,遵循左闭右开原则,str[0,2] 是不包含第 3 个字符的。 a[1:4] 输出结果 ell
print("我叫 %s 今年 %d 岁, 我的弟弟 %f 岁!" % ('小明', 10, 7.5))
输出: 我叫 小明 今年 10 岁, 我的弟弟 7.500000 岁!
三引号可以允许输入多行字符串,三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。
一个典型的用例是,当你需要一块HTML或者SQL时,这时用字符串组合,特殊字符串转义将会非常的繁琐。
para_str = """这是Python一个实用的语法,避免了各种转义带来的困扰
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print(para_str)
例如:
errHTML = '''
Friends CGI Demo
error
'''
print(errHTML)
say = 'hello'
print(say.capitalize())
输出:Hello
首字母大写
s1 = 'help'
print(s1.center(100, '-'))
------------------------------------------------help------------------------------------------------
返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。
find(str, beg=0 end=len(string))
检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1
str.join(sequence)用于将序列中的元素以指定的字符连接生成一个新的字符串
operator = '+'
expression = ['x**x', 'y**y']
result = 'r**r'
print(operator.join(expression) + '=' + result)
lstrip()、rstrip()、strip()表示去除字符串中的空格,l=left, r=right
min(str)、max(str)表示返回字符串中最小/大字母。
如:print(min('apple')) , 则输出: a
str.swapcase()
print('Apple'.swapcase())
输出: aPPLE
将字符串中大写转换为小写,小写转换为大写,奇葩的函数
返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
print('apple or huawei ?'.title())
输出:Apple Or Huawei ?
str.upper() / str.lower() , 将字符串转换为大写或小写
1、Python中序列的内置类型分别有哪些
Python内建的序列,有列表、元组、字符串(str、bytes)、buffer对象和 xrange 对象。(numpy中的array也是序列但不是python内建的序列,array与list的异同:array的数据项必须是同一类型,list可以不是)序列通用的操作包括:索引、长度、组合(序列相加)、重复(乘法)、分片、检查成员、遍历、最小值和最大值。
2、 列表和元组的异同:
Python有6个序列的内置类型,但最常见的是列表和元组。
列表和元组相似,具体包含下面几个方面:
相同点:
1、均具有序列的特性,均可以进行序列通用的操作;
2、通常均使用括号表示,且括号内的元素以逗号分隔值出现,数据项均不需要具有相同的类型;
3、均包含内置函数max、min、len;
4、均可以转换为对方;
异同点:
1、定义不同
1)列表使用方括号括起来的。
2)元组使用小括号括起来的。
2、是否可修改
1)列表可修改
2)元组不可修改
3、转换方式
1)列表转元组:tuple(seq)
2)元组转列表: list(seq)
4、是否含内置方法
1)列表提供11个内置方法list.append(obj)、list.count(obj)、list.extend(seq)、list.index(obj)、list.insert(index, obj)、list.pop([index=-1]])、list.remove(obj)、list.reverse()、list.sort(cmp=None, key=None, reverse=False)、list.clear()、list.copy();
2)元组未提供内置方法
【转载】内置序列类型概览
按照可否存储不同数据类型来分,可以分为容序列和扁平序列。
容器序列
list, tuple, collections.deque 这些序列类型可以容纳不同类型的数据。
扁平序列
str, bytes, bytearray, memoryview, array.array 这类序列只能容纳一种类型的数据
按照是否可变可以分为可变序列和不可变序列。
可变序列
list, bytesarray, array.array, collections.deque, memoryview
不可变序列
tuple, str, bytes
更多序列知识可参考:https://andrewpqc.github.io/2017/10/29/chapter-two-of-fluent-python/
a,b=b,a
import collections
d = collections.deque()
常用方法:
详细用法见:双向队列
详细见:序列不可变分析
Python列表函数&方法
Python包含以下函数:
序号 函数
1 len(list)
列表元素个数
2 max(list)
返回列表元素最大值
3 min(list)
返回列表元素最小值
4 list(seq)
将元组转换为列表
Python包含以下方法:
序号 方法
1 list.append(obj)
在列表末尾添加新的对象
2 list.count(obj)
统计某个元素在列表中出现的次数
3 list.extend(seq)
在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4 list.index(obj)
从列表中找出某个值第一个匹配项的索引位置
5 list.insert(index, obj)
将对象插入列表
6 list.pop([index=-1])
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7 list.remove(obj)
移除列表中某个值的第一个匹配项
8 list.reverse()
反向列表中元素
9 list.sort( key=None, reverse=False)
对原列表进行排序
10 list.clear()
清空列表
11 list.copy()
复制列表
空元组:tup = ()
元组不用括号也可以
tup1 = ('a', 'b', 'c', 'd',)
tup2 = "a", "b", "c", "d",
print(tup1, tup2)
输出:('a', 'b', 'c', 'd') ('a', 'b', 'c', 'd')
元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:
如下所示: print(type((10))) 输出:; print(type((10, ))) 输出:
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合或重新赋值操作
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组
Python元组包含了以下内置函数:
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
举例如下:
dict1 = {(20,): 3, (30,): 4, 'key1': 'value1', 2: 3, }
print(dict1)
输出: {(20,): 3, (30,): 4, 'key1': 'value1', 2: 3}
其中:键取得值分别为元组、字符串、数字这些不可变对象
字典删除操作:包括del(删除某一项或整个字典)、pop(删除指定某一项,区别于del, pop删除后仍可以访问,如 item1 dict1.pop(‘key1’), 后面item1的值一直可用)、popitem(删除最后一项)
dict1 = {(20,): 3, (30,): 4, 'key1': 'value1', 2: 3, }
dict1.pop('key1') 删除的为指定的某一项
dict1.popitem() 删除的为字典最后一项
print(dict1)
集合(set)是一个无序的不重复元素序列。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
下面展示两个集合间的运算.
a = set('abracadabra')
b = set('alacazam')
print(a)
{'a', 'r', 'b', 'c', 'd'}
print( a - b) # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
print(a | b) # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
print(a & b) # 集合a和b中都包含了的元素
{'a', 'c'}
print(a ^ b) # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}
类似列表推导式,同样集合支持集合推导式(Set comprehension):
a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)
输出:{'r', 'd'}
集合内置方法完整列表
方法 描述
while 循环使用 else 语句,在 while … else 在条件语句为 false 时执行 else 的语句块,循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。
没有do…while这种语法
Python pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句,如下实例
for循环:同样也可以使用else语句块表示不满足for循环情况下执行的语句
for in :
else:
两种方式遍历列表
a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
for i, com in enumerate(a):
print(i, com)
for i in range(len(a)):
print(i, a[i])
往往有这样的观点:能不用递归就不用递归,递归都可以用迭代来代替。
诚然,在理论上,递归和迭代在时间复杂度方面是等价的(在不考虑函数调用开销和函数调用产生的堆栈开销),但实际上递归确实效率比迭代低,既然这样,递归没有任何优势,那么是不是就,没有使用递归的必要了,那递归的存在有何意义呢?
万物的存在是需要时间的检验的,递归没有被历史所埋没,即有存在的理由。从理论上说,所有的递归函数都可以转换为迭代函数,反之亦然,然而代价通常都是比较高的。但从算法结构来说,递归声明的结构并不总能够转换为迭代结构,原因在于结构的引申本身属于递归的概念,用迭代的方法在设计初期根本无法实现,这就像动多态的东西并不总是可以用静多态的方法实现一样。这也是为什么在结构设计时,通常采用递归的方式而不是采用迭代的方式的原因,一个极典型的例子类似于链表,使用递归定义及其简单,但对于内存定义(数组方式)其定义及调用处理说明就变得很晦涩,尤其是在遇到环链、图、网格等问题时,使用迭代方式从描述到实现上都变得不现实。 因而可以从实际上说,所有的迭代可以转换为递归,但递归不一定可以转换为迭代。
采用递归算法需要的前提条件是,当且仅当一个存在预期的收敛时,才可采用递归算法,否则,就不能使用递归算法。
递归其实是方便了程序员难为了机器,递归可以通过数学公式很方便的转换为程序。其优点就是易理解,容易编程。但递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,对嵌套层数深的一些算法,递归会力不从心,空间上会以内存崩溃而告终,而且递归也带来了大量的函数调用,这也有许多额外的时间开销。所以在深度大时,它的时空性就不好了。
而迭代虽然效率高,运行时间只因循环次数增加而增加,没什么额外开销,空间上也没有什么增加,但缺点就是不容易理解,编写复杂问题时困难。
Python中的tuple大家应该都非常熟悉了。它可以存储一个Python对象序列。与list不同的是,你不能改变tuple中元素的值。tuple的元素是通过索引进行访问的:
fruits = ('apple', 'banana', 'orange')
print(fruits[0])
输出:apple
Tuple还有一个兄弟,叫namedtuple。虽然都是tuple,但是功能更为强大。对于namedtuple,你不必再通过索引值进行访问,你可以把它看做一个字典通过名字进行访问,只不过其中的值是不能改变的。
from collections import namedtuple
fruits_count = namedtuple('fruits_count', 'apple banana orange peach')
或者这样写:fruits_count = namedtuple('fruits_count', ['apple', 'banana', 'orange', 'peach'])
my_fruits_count = fruits_count(apple=200, banana=400, orange=400, peach=500)
print(my_fruits_count)
print('we need to buy %d apples and %d bananas' % (my_fruits_count.apple, my_fruits_count.banana), )
输出:fruits_count(apple=200, banana=400, orange=400, peach=500)
we need to buy 200 apples and 400 bananas
为了构造一个namedtuple需要两个参数,分别是tuple的名字和其中域的名字。比如在上例中,tuple的名字是“fruits_count”,它包括四个域,分别是“apple”、“banana”和“orange”和‘peach’。
Namedtuple比普通tuple具有更好的可读性,可以使代码更易于维护。同时与字典相比,又更加的轻量和高效。但是有一点需要注意,就是namedtuple中的属性都是不可变的。任何尝试改变其属性值的操作都是非法的。
Namedtuple还有一个非常好的一点是,它与tuple是完全兼容的。也就是说,我们依然可以用索引去访问一个namedtuple。
在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="Runoob"
以上代码中,[1,2,3] 是 List 类型,“Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针), 可以是指向 List 类型对象,也可以是指向 String 类型对象。
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
加了两个星号 ** 的参数会以字典的形式导入。
声明函数时,参数中星号 * 可以单独出现,如果单独出现星号 * 后的参数必须用关键字传入。
匿名函数,python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
举例如下:
def f(arg1, *args_tuple, **args_dict):
"""测试元组和字典作为参数传递"""
print(arg1, args_tuple, args_dict)
f(10, 15, 17, a='12', b=14, c=16)
def fax(a, *, b, c, d):
"""测试*单独出现后面的参数都要用关键字传入"""
print(a, b, c, d)
fax(1, b=2, c=3, d=4)
输出:
10 (15, 17) {'a': '12', 'b': 14, 'c': 16}
1 2 3 4
变量作用域
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内置作用域(内置函数所在模块的范围)
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
g_count = 0 # 全局作用域
def outer():
o_count = 1 # 闭包函数外的函数中
def inner():
i_count = 2 # 局部作用域
内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:
import builtins
dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:
if True:
msg = 'I am from Runoob'
输出: msg
'I am from Runoob'
实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。
如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:
def test():
msg_inner = 'I am from Runoob'
输出: msg_inner
Traceback (most recent call last):
File "", line 1, in
NameError: name 'msg_inner' is not defined
从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:
实例(Python 3.0+)
#!/usr/bin/python3
total = 0 # 这是一个全局变量
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量.
print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)
以上实例输出结果:
函数内是局部变量 : 30
函数外是全局变量 : 0
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
以下实例修改全局变量 num:
实例(Python 3.0+)
#!/usr/bin/python3
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)
以上实例输出结果:
1
123
123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
实例(Python 3.0+)
#!/usr/bin/python3
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
以上实例输出结果:
100
100
另外有一种特殊情况,假设下面这段代码被运行:
实例(Python 3.0+)
#!/usr/bin/python3
a = 10
def test():
a = a + 1
print(a)
test()
以上程序执行,报错信息如下:
Traceback (most recent call last):
File "test.py", line 7, in
test()
File "test.py", line 5, in test
a = a + 1
UnboundLocalError: local variable ‘a’ referenced before assignment
错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。
修改 a 为全局变量,通过函数参数传递,可以正常执行输出结果为:
实例(Python 3.0+)
#!/usr/bin/python3
a = 10
def test(a):
a = a + 1
print(a)
test(a)
执行输出结果为:
11
python3中
round(0.5)
0
round(0.6)
1
round(1.5)
2
round(2.5)
2
round(2.6)
3
round(3.5)
4
round(4.5)
4
round(5.5)
6
round(6.5)
6
可以简单的记忆为:整数部分为偶数时就舍去,为奇数时就进一,实际上是:如果距离两边一样远,会保留到偶数的一边(python文档中写的)
round(3.1415926, 2)
结果为:3.14
其中:第二个参数表示保留到第二位小数
更多详情可以查看:python3中round使用异常情况原因
fruits = [1, 2, 3, '4', 5, ]
vegetables = [10, 11, 13, 12, 14]
fruits += vegetables
fruits[len(fruits):] = vegetables
fruits.extend(vegetables)
上面三句是等效的都是把两个列表合并到一个列表中
print(fruits)
fruits.clear()
del fruits
1. clear与del还是不同的,一个是清空数据,另一个直接删除对象,删除后对象不能访问,清空后仍可访问
2. 使用 del 语句可以从一个列表中依索引而不是值来删除一个元素。这与使用 pop() 返回一个值不同。可以用 del 语句从列表中删除一个切割,或 清空整个列表(我们以前介绍的方法是给该切割赋一个空列表)
3. 如: del fruits[2:4]表示删除删除一个切片
print(fruits)
print(fruits.index(5))
输出:
[1, 2, 3, '4', 5, 10, 11, 13, 12, 14]
[1, 2, 3, '4', 5, 10, 11, 13, 12, 14]
4
注意三者的区别:
1. 列表推导式:a = [x for x in range(5) if x < 4] 结果为:[0,1,2,3]
2. 集合推导式:a = {x for x in 'abracadabra' if x not in 'abc'} 结果为:{'r', 'd'}
3. 字典推导式:a = {x: x**2 for x in (2, 4, 6)} 结果为:{2: 4, 4: 16, 6: 36}
补充:
print([(x * y, x + y) for x, y in zip([1, 3, 5], [2, 4, 6]) if (x > 2 and y >= 4)])
输出:[(12, 7), (30, 11)]
说明:用zip可以实现遍历多个列表来使用推导式
1. 同时遍历两个或更多的序列,可以使用 zip() 组合:
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
print('What is your {0}? It is {1}.'.format(q, a))
输出:
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
2. 要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数:
for i in reversed(range(1, 10, 2)):
print(i)
输出:
9
7
5
3
1
3. 要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for f in sorted(set(basket)):
print(f)
输出:
apple
banana
orange
pear
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
说明: 每个模块都有一个__name__属性,当其值是’main’时,表明该模块自身在运行,否则是被引入。
说明:name 与 main 底下是双下划线, _ _ 是这样去掉中间的那个空格。
举例:
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
运行输出如下:
$ python using_name.py
程序自身在运行
Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。相对于老版的%格式方法,它有很多优点。
1、按照默认顺序,不指定位置
print("{} {}".format("hello","world") )
输出:hello world
2、设置指定位置,可以多次使用
print("{0} {1} {0}".format("hello","or"))
输出:hello or hello
3、使用列表格式化
person = {"name":"kingspacing","age":20}
print("My name is {name} . I am {age} years old .".format(**person))
输出: My name is kingspacing. I am 20 years old .
或者字典格式化:
table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
上面两种方式等效
输出: Runoob: 2; Google: 1; Taobao: 3
4、通过列表格式化
stu = ["kingspacing","linux","MySQL","Python"]
print("My name is {0[0]} , I love {0[1]} !".format(stu))
输出:My name is kingspacing, I love linux !
数字格式化
数字 格式 输出 描述
3.1415926 {:.2f} 3.14 保留小数点后两位
3.1415926 {:+.2f} +3.14 带符号保留小数点后两位
-1 {:+.2f} -1.00 带符号保留小数点后两位
2.71828 {:.0f} 3 不带小数
5 {:0>2d} 05 数字补零 (填充左边, 宽度为2)
5 {:x<4d} 5xxx 数字补x (填充右边, 宽度为4)
10 {:x<4d} 10xx 数字补x (填充右边, 宽度为4)
1000000 {:,} 1,000,000 以逗号分隔的数字格式
0.25 {:.2%} 25.00% 百分比格式
1000000000 {:.2e} 1.00e+09 指数记法
13 {:10d} 13 右对齐 (默认, 宽度为10)
13 {:<10d} 13 左对齐 (宽度为10)
13 {:^10d} 13 中间对齐 (宽度为10)
进制转换
11 '{:b}'.format(11) 1011 二进制
11 '{:d}'.format(11) 11 十进制
11 '{:o}'.format(11) 13 八进制
11 '{:x}'.format(11) b 十六进制
11 '{:#x}'.format(11) 0xb 十六进制
11 '{:#X}'.format(11) 0XB 十六进制
^, <, > 分别是居中、左对齐、右对齐,后面带宽度, : 号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。
+ 表示在正数前显示 +,负数前显示 -; (空格)表示在正数前加空格
b、d、o、x 分别是二进制、十进制、八进制、十六进制。
输出大括号
print("{} {{0}}".format("kingspacing_linux"))
输出:kingspacing_linux {0}