元组 – tuple
基本概念
-
1. 一个有序的元素组成的集合.
-
2. 使用小括号()表示.
-
3. 元组是不可变对象(里面的引用类型可变).
-
4. 可理解为只读.
定义及初始化
tuple() -> empty tuple
tuple(iterable) -> tuple initialized fromiterable's items.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
In [1]: t = tuple() # 工厂方法,构造完不能往里面添加元素.
In [2]: type(t) Out[2]: tuple
In [3]: tt = ()
In [4]: type(tt) Out[4]: tuple
In [5]: ttt = (1)
In [6]: type(ttt) Out[6]: int
In [7]: ttt = (1,) # 构造一个元素的元组时,不加逗号会被误认为其他类型,此处只是以数字为例.
In [8]: type(ttt) Out[8]: tuple
In [9]: ttt Out[9]: (1,)
In [10]: ttt * 6 Out[10]: (1, 1, 1, 1, 1, 1)
In [11]: ttt Out[11]: (1,) # 一个元素元组的定义.
In [12]: p = tuple(range(1, 8)) # iterable.
In [13]: p Out[13]: (1, 2, 3, 4, 5, 6, 7)
In [14]: |
元素访问
支持索引(下标).
正索引: 从左到右,从零开始,为元组中每个元素编号.
负索引: 从右到左,从负一开始.
正索引不可超界,否则引发异常IndexError.
元组通过索引访问: tuple[index], index即索引,使用中括号访问.
查询
查找元素: T.index(value,[start, [stop]]) -> integer -- return first index of value.
注: 匹配到第一个就立即返回索引,匹配不到则报错ValueError.
统计次数: T.count(value)-> integer -- return number of occurrences of value.
注: 返回元组中匹配value的次数.
时间复杂度: index和count方法都是O(n),随着元组规模增大,效率下降.
len(tuple):返回元组中元素的个数.
其他操作
元组只读,所以增删改的方法都没有.
命名元组 - namedtuple
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
In [1]: from collections import namedtuple
In [2]: help(namedtuple) Help on function namedtuple in module collections:
namedtuple(typename, field_names, verbose=False, rename=False) Returns a new subclass of tuple with named fields.
>>> Point = namedtuple('Point', ['x', 'y']) >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable like a plain tuple 33 >>> x, y = p # unpack like a regular tuple >>> x, y (11, 22) >>> p.x + p.y # fields also accessible by name 33 >>> d = p._asdict() # convert to a dictionary >>> d['x'] 11 >>> Point(**d) # convert from a dictionary Point(x=11, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=100, y=22)
In [3]: |
注: 命名元组,返回一个元组的子类,并定义了字段.
field_names可以是空格或逗号分割的字段的字符串,可以是字段的列表.
冒泡法 – bubble
属于交换排序.
两两比较大小,交换位置,如同水泡咕咚咕咚往上冒.
结果分为升序排列和降序排列.
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 生成20个整齐有序的list整数元素. lst = [] for i in range(1, 21): lst.append(i)
# 导入随机数,使用shuffle方法将list内元素打乱,使其乱序排列. from random import shuffle shuffle(lst)
# 冒泡法排序 length = len(lst) count = 0 # 统计循环次数 count_swap = 0 # 统计元素间交换次数. for j in range(length): flag = True # 设定一个标记,判断该list是否有序. count += 1 for x in range(length-j-1): if lst[x] > lst[x+1]: lst[x], lst[x+1] = lst[x+1], lst[x] count_swap += 1 flag = False if flag: break print('lst: {}, count: {}, count_swap: {}'.format(lst, count, count_swap))
|
总结:
冒泡法需要数据一轮轮比较.
可以设定一个标记(比如flag)判断此轮是否有数据交换发生,如果没有发生交换,则结束排序,否则继续下一轮排序.
最差的排序情况: 初始顺序与目标顺序完全相反,遍历次数1,…,n-1之和n(n-1)/2.
最好的排序情况: 初始顺序与目标顺序完全相同,遍历次数n-1.
时间复杂度: O(n2).
练习
依次接收用户输入的3个数,排序后打印.
转换int后,判断大小排序.
使用max, min函数
使用列表sort方法.
使用冒泡法.
第一种方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
while True: lst = [] for i in range(1, 4): num = input('第{}个整数: '.format(i)) if num.isdigit(): lst.append(int(num)) if len(lst) == 3: break else: print('输入错误,请重新输入3个整数.')
t = [] if lst[0] > lst[1]: if lst[2] > lst[1]: if lst[0] > lst[2]: t = [0, 2, 1] else: t = [2, 0, 1] else: t = [0, 1, 2] else: # lst[0] < lst[1] if lst[1] < lst[2]: t = [2, 1, 0] else: # lst[1] > lst[2] if lst[0] > lst[2]: t = [1, 0, 2] else: t = [1, 2, 0] print('三个数的顺序为: {}, {}, {}'.format(lst[t[2]], lst[t[1]], lst[t[0]])) #从小到大排列. |
第二种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
while True: lst = [] for i in range(1, 4): num = input('第{}个整数: '.format(i)) if num.isdigit(): lst.append(int(num)) if len(lst) == 3: break else: print('输入错误,请重新输入3个整数.')
max_number = max(lst) min_number = min(lst) middle_number = '' for j in lst: if j != max_number and min_number: middle_number = j print('排序结果为: {}, {}, {}'.format(min_number, middle_number, max_number)) |
第三种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
while True: lst = [] for i in range(1, 4): num = input('第{}个整数: '.format(i)) if num.isdigit(): lst.append(int(num)) if len(lst) == 3: break else: print('输入错误,请重新输入3个整数.')
lst.sort() print('排序结果为: {}'.format(lst)) |
第四种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
while True: lst = [] for i in range(1, 4): num = input('第{}个整数: '.format(i)) if num.isdigit(): lst.append(int(num)) if len(lst) == 3: break else: print('输入错误,请重新输入3个整数.')
length = len(lst) for j in range(length): flag = True for x in range(length-i-1): if lst[x] > lst[x+1]: lst[x], lst[x+1] = lst[x+1], lst[x] flag = False if flag: break print('排序结果为: {}'.format(lst)) |
字符串 – str
基本概念
-
a) 一个个字符组成的有序的序列,是字符的集合.
-
b) 使用单引号,双引号,三引号引住的字符序列.
-
c) 字符串是不可变对象
-
d) Python3起,字符串就是Unicode类型.
定义及初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
In [2]: s1 = 'string'
In [3]: s2 = '''this's a "String"'''
In [4]: s2 Out[4]: 'this\'s a "String"'
In [5]: s3 = 'c:\windows\nt'
In [6]: print(s3) c:\windows t
In [7]: s3 = r'c:\windows\nt' # 'r'或'R'表示转义.
In [8]: print(s3) c:\windows\nt
In [9]: |
元素访问
-
1. 支持索引访问.
-
2. 是有序的字腹肌和,字符序列.
-
3. 可迭代.
修改
S.replace(old, new[,count]) -> str
注: 字符串中找到匹配替换为新子串,返回新字符串.
count表示替换几次,不指定就是全部替换.
1 2 3 4 5 6 7 8 9 10 |
In [2]: 'www.jotting.cn'.replace('www', 'blog') Out[2]: 'blog.jotting.cn'
In [3]: 'www.jotting.cn'.replace('w', 'one') Out[3]: 'oneoneone.jotting.cn'
In [4]: 'www.jotting.cn'.replace('w', 'one', 2) Out[4]: 'oneonew.jotting.cn'
In [5]: |
S.strip([chars])-> str
注: strip用于从字符串两端去除指定的字符串集chars中的所有字符.
如果chars没有指定,则默认去除两端的空白字符.
从右开始: S.rstrip([chars])-> str
从左开始: S.lstrip([chars])-> str
查找
S.find(sub[, start[,end]]) -> int
注: 在指定区间[start, end),从左至右查找子串sub,找到返回索引值,没找到返回-1.
S.rfind(sub[, start[, end]]) -> int
注: 在指定区间[start, end),从右至左查找子串sub,找到返回索引值,没找到返回-1.
S.index(sub[,start[, end]]) -> int
注: 在指定区间[start, end),从左至右查找子串sub,找到返回索引值,没找到抛异常ValueError.
S.rindex(sub[, start[, end]]) -> int
注: 在指定区间[start, end),从右至左查找子串sub,找到返回索引值,没找到抛异常ValueError.
S.count(sub[,start[, end]]) -> int
注: 在指定区间[start, end),从左至右,统计子串sub出现的次数.
时间复杂度:
index和count方法都是O(n).
随着字符串数据规模增大,效率下降.
len(string):
返回字符串的长度,即字符的个数.
其他操作
join连接字符串:S.join(iterable)-> str
注: 将可迭代对象连接起来,使用string作为分隔符.
可迭代对象元素本身都是字符串.
返回一个新的字符串.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
In [15]: string = bytes(range(97, 123)).decode()
In [16]: string Out[16]: 'abcdefghijklmnopqrstuvwxyz'
In [17]: '/'.join(string) Out[17]: 'a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z'
In [18]: lst = ['p', 'y', 't', 'h', 'o', 'n']
In [19]: ''.join(lst) Out[19]: 'python'
In [20]: |
字符串+连接 '+' -> str
注: 将2个字符串连接在一起,返回一个新字符串.
字符串分割
split系:
S.split(sep=None, maxsplit=-1) ->list of strings
注: 将字符串按照分隔符分割成若干字符串,并返回列表.
从左至右
sep指定分割字符串,缺省的情况下以空白字符串作为分隔符.
maxsplit指定分割的次数,-1表示遍历整个字符串.
S.rsplit(sep=None, maxsplit=-1) ->list of strings
注: 从右往左, 其余和split用法一样.
S.splitlines([keepends]) -> listof strings
注: 按照行来切分字符串.
keepends指是否保留行分隔符.
行分隔符包括: \n, \r\n, \r等.
partition系:
S.partition(sep) -> (head, sep,tail)
注: 将字符串按照分隔符分割成2段,返回这2段和分隔符的元组.
从左到右,遇到分隔符就把字符串分割成两部分,返回头,分隔符,尾三部分的三元组;如果没有找到分隔符,就返回头,2个空元素的三元组.
sep分割字符串,必须指定.
S.rpartition(sep) -> (head, sep,tail)
注: 从右往左, 其余和partition用法一样.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
In [28]: string = 'Hello Python'
In [29]: string.split(' ') Out[29]: ['Hello', 'Python']
In [30]: string.split('P') Out[30]: ['Hello ', 'ython']
In [31]: string.partition(' ') Out[31]: ('Hello', ' ', 'Python')
In [32]: string.partition('P') Out[32]: ('Hello ', 'P', 'ython')
In [33]: s1 = 'learning python\nhello python'
In [34]: s1.splitlines() Out[34]: ['learning python', 'hello python'] |
字符串大小写
upper(), 全大写.
lower(), 全小写.
大小写,做判断的时候用.
swapcase(), 交互大小写.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
In [43]: 'ACE'.swapcase() Out[43]: 'ace'
In [44]: 'abc'.upper() Out[44]: 'ABC'
In [45]: 'abc'.swapcase() Out[45]: 'ABC'
In [46]: 'ABC'.lower() Out[46]: 'abc'
In [47]: 'ABC'.swapcase() Out[47]: 'abc'
In [48]: |
字符串排版
title() -> str
标题的每个单词都大写.
capitalize() -> str
首个单词大写.
center(width[,fillchar]) -> str
width 打印宽度.
fillchar 填充的字符.
zfill(width) -> str
width 打印宽度,居右,左边用0填充.
ljust(width[,fillchar]) -> str 左对齐.
rjust(width[,fillchar]) -> str右对齐.
注: 以上中文用的少.
字符串判断
S.startswith(prefix[, start[,end]]) -> bool
注: 在指定区间[start, end),字符串是否是prefix开头.
S.endswith(suffix[, start[, end]]) -> bool
注: 在指定区间[start, end),字符串是否是suffix结尾.
1 2 3 4 5 6 7 8 9 |
In [50]: string = 'Hello Python'
In [51]: string.startswith('Hel') Out[51]: True
In [52]: string.endswith('thon') Out[52]: True
In [53]:
|
字符串判断is系列
isalnum() -> bool 判断是否是字母和数字组成
isalpha() 是否是字母.
isdecimal() 是否只包含十进制数字.
isdigit() 是否全部是数字.
isidentifier() 是否是字母和下划线开头, 其他都是数字,字母,下划线.
islower() 是否都是小写.
isupper() 是否全部大写.
isspace() 是否只包含空白字符.
字符串格式化
字符串的格式化是一种拼接字符串输出样式的手段,更灵活方便.
join拼接只能使用分隔符,且要求被拼接的是可迭代对象.
+ 拼接字符串还算方便,但是非字符串需要先转换为字符串才能拼接.
%占位符:%s: 万能; %d: 整数; %f: 浮点数.
1 2
|
In [53]: "my name is %s, and I'm %s years old" %('ames', 22) Out[53]: "my name is ames, and I'm 22 years old"
|
format函数格式字符串:python鼓励使用.
语法: '{}{xxx}'.format(*args,**kwargs)-> str.
args是位置参数,是一个元组.
kwargs是关键字参数,是一个字典.
{}表示占位符.
1 2 3 4 5
|
In [54]: 'I want to say: {1} {0}'.format('hello', 'wolrd') Out[54]: 'I want to say: wolrd hello'
In [55]: '{} {}:{}'.format('Hello', 'all', 'world') Out[55]: 'Hello all:world' |
练习
-
1. 用户输入一个数字:
判断是几位数
打印每一位数字及其重复的次数.
依次打印每一位数字,顺序按个,十,百,千,万…位.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
while True: number = input('number: ').strip('0').strip(' ') if number.isdigit(): break else: print('输入错误,重新输入.')
length = len(number) # length = max([int(i) for i in number]) + 1
# 打印每一位数字及其出现的次数. lst = [0] * 10
for i in range(10): lst[i] = number.count(str(i)) if lst[i]: print('The count of {} is {}'.format(i, lst[i]))
# 按个,十,百,千,万…位的顺序倒序排列. # print([i for i in reversed([x for x in number])])
# 倒序打印1 for i in reversed(number): print(i, end = ' ') print()
# 倒序打印2 for i in range(len(number), 0, -1): print(number[i-1], end = ' ') print()
# 负索引方式打印 for i in range(len(number)): print(number[-i-1], end = ' ') print() |
-
2. 输入5个数字,依次打印每个数字的位数,将这些数字排序打印,要求升序排列.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
while True: lst = [] for i in range(1, 6): number = input('输入第{}个数: '.format(i)).strip('0').strip(' ') if not number.isdigit(): print('输入错误,重新输入.') break print('第{}个数的位数为{}.'.format(i, len(number))) lst.append(int(number))
if len(lst) == 5: break
# sort排序 nums = lst.copy() nums.sort() print(nums)
# 冒泡排序 length = len(lst) for i in range(length): flag = True for j in range(length-i-1): if lst[j] > lst[j+1]: tmp = lst[j] lst[j] = lst[j+1] lst[j+1] = tmp flag = False if flag: break print(lst) 本文转自 羽丰1995 51CTO博客,原文链接:http://blog.51cto.com/13683137989/1970806 |