抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

[toc]

python 集合、 字典

集合

  • 基本概念
    全集:所有元素的集合。例如实数集,所有实数组成的集合就是全集;
    子集subset和超集superset: 一个集合A所有元素都在另一个集合B是A的真超集;
    并集: 多个集合合并的结果;
    交集: 多个集合的公共部分;
    差集: 集合中除去和其他集合公共部分。

并集

将多个集合A和B的所有的元素合并到一起
union(*others)
返回和多个集合合并后的新的集合
运算符重载,等同union
update(*others)
和多个集合合并,就地修改
|=
等同update

In [8]: a = {1,2,3}
In [9]: b = {2,3,4}
In [10]: c = b.union(a)
In [11]: c
Out[11]: {1, 2, 3, 4}
In [29]: a = {1,2,3,4}
In [30]: b = {2,3,4,5}
In [31]: b.update(a)
In [32]: b
Out[32]: {1, 2, 3, 4, 5}

交集

  • 集合A和B,由所有属于A且属于B的元素组成的集合
    intersection(*others)
  • 返回和多个集合的交集
    & 等同insersection
    intersection_update(*others)
    获取和多个集合的交集,并就地修改
    &=
    等同intersection_update
In [1]: a={1,2,3}
In [2]: b={3,4,5}
In [3]: c = a & b
In [4]: c
Out[4]: {3}
Out[7]: {3}
In [8]: a.intersection_update(b)
In [9]: a
Out[9]: {3}

差集

集合A和B,是所有属于A且不属于B的元素组成的集合
difference(*others)
返回和多个集合的差集
- 等同difference
difference_update(*others)
获取和多个集合的差集并就地修改
-=
等同difference_update

In [10]: a.update({1,2,3,4,5,6})
In [11]: a
Out[11]: {1, 2, 3, 4, 5, 6}
In [12]: b.update({3,4,5})
In [13]: a - b
Out[13]: {1, 2, 6}
In [15]: a -= b
In [16]: a
Out[16]: {1, 2, 6}

对称差集

集合A和B,由所有不属于A和B的交集元素组成的集合,记作(A-B)U(B-A)
symmetric_differece(other)
返回和另一个集合的差集
^
等同于symmetric_differece
symmetric_differece_update(other)
获取和另一个集合的差集并就地修改
^=
等同于symmetric_differece_update

In [17]: a = {1,2,3,4}
In [18]: b = {2,3,4}
In [19]: a ^ b
Out[19]: {1}
In [20]: a ^= b
In [21]: a
Out[21]: {1}

集合运算

issubset(other)、<=
判断当前集合是否是另一个集合的子集
set1 < set2
判断set1是否是set2的真子集
issuperset(other)、>=
判断当前集合是否是other的超集
set1 > set2
判断set1是否是set的真超集
isdisjoint(other)
当前集合和另一个集合没有交集
没有交集,返回Ture

In [1]: a = {1,2,3}
In [2]: b = {1,2,3,4}
In [3]: b.issuperset(a)
Out[3]: True

set 和线性结构

  • 线性结构的查询时间复杂度是O(n),即随着数据规模的增大而增加耗时
  • set、dict 等结构,内部使用hash值作为key,时间复杂度可以做O(1),查询时间和数据规模无关

可hash 的数据类型
数据型 int、float、complex
布尔型 True、False
字符串string、bytes
tuple
None
以上都是不可变类型,成为可哈希类型 ,hashble

  • set 的元素必须是可hash的

简单选择排序

  • 属于选择排序
  • 两两比较在大小,找出极值(极大值或极小值)被放置在固定的位置,这个固定位置一般指的是某一端
  • 结果分为升序和降序列
  • 降序

    n 个数从左至右,索引从0开始到n-1,两两依次比较,记录大值过引,此轮所有数比较完比,将大数和索引0数效换,如果大数就是索引1,不交换,第二轮,从1开始比较,找到最大值,将它和过引1位置交换,如果它就在过引1 位置则不交换。今次类推,每次左边都会固定下一个大数。

  • 升序

    和降序相反

简单选择排序代码实现(一)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
m_list = [
    [1,9,8,5,6,7,4,3,2],
    [1,2,3,4,5,6,7,8,9],
    [9,8,7,6,5,4,3,2,1]
]

nums = m_list[1]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0

for i in range(length):
    maxindex = i
    for j in range(i+1,length):
        count_iter +=1
        if nums[maxindex] < nums[j]:
            maxindex = j
    if i != maxindex:
        tmp = nums[i]
        nums[i] = nums[maxindex]
        nums[maxindex] = tmp
        count_swap +=1
print(nums,count_swap,count_iter)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1] 4 36

简单选择排序代码实现(二),二元排序法

#!/usr/bin/env python
# -*- coding: utf-8 -*-
m_list = [
    [1,9,8,5,6,7,4,3,2],
    [1,2,3,4,5,6,7,8,9],
    [9,8,7,6,5,4,3,2,1]
]

nums = m_list[1]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0


for i in range(length // 2):
    maxindex = i
    minindex = -i -1
    minorigin = minindex

    for j in range(i + 1, length -i):
        count_iter += 1
        if nums[maxindex] < nums[j]:
            maxindex = j

        if nums[minindex] > nums[-j -1]:
            minindex = -j -1
        print(maxindex,minindex)

    if i != maxindex:
        tmp = nums[i]
        nums[i] = nums[maxindex]
        nums[maxindex] = tmp
        count_swap += 1

        if i == minindex or i == length + minindex:
            minindex = maxindex
    if minorigin != minindex:
        tmp = nums[minorigin]
        nums[minorigin] = nums[minindex]
        nums[minindex] = tmp
        count_swap +=1
print(nums, count_swap,count_iter)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1 -2
2 -3
3 -4
4 -5
5 -6
6 -7
7 -8
8 -9
2 -3
3 -4
4 -5
5 -6
6 -7
7 -8
3 -4
4 -5
5 -6
6 -7
4 -5
5 -6
[9, 8, 7, 6, 5, 4, 3, 2, 1] 8 20

简单选择排序总结

  • 简单选择排序需要数据一轮轮比较,并在每一轮中发现极值
  • 没有办法知道当前轮是否已经达到排序要求,但是可以知道极值是滞在目标索引位置上
  • 遍历次数1,…,n-1之后n(n-1)/2
  • 时间复杂度O(n2次方)
  • 减少了交换次数,提高了效率,性能略好于冒泡法

字典dict

可变的、无序的 、key 不重复

字典dict定义 初始化

  • d = dict() 或者 d={}
  • dict(**kwargs)使用name=value 对初始化一个字典
  • dcit(iterable,**kwarg) 使用可迭代对象征和name=value对构造字典,不过可迭代对象的元素必须是一个二元结构
  • d = dict(((1,’a’),(2,’b’))) 或者 d = dict(([1,’a’],[2,’b’]))
  • dict(mapping, ** kwarg)使用一个字典构建另一个字典
    d = {'a':10,'b':20,'c':None,'d':[1,2,3]}

例: 常用的变量赋值

In [1]: d = dict(a=5,b=6,z=[123])
In [2]: d
Out[2]: {'a': 5, 'b': 6, 'z': [123]}
In [43]: d = dict(((1,'a'),))
In [44]: d
Out[44]: {1: 'a'}
In [45]: d = dict(([1,'a'],[2,'b']))
In [46]: d
Out[46]: {1: 'a', 2: 'b'}

类方法使用时需要注意

In [47]: d1 = dict.fromkeys(range(1,11),[1,2])

In [48]: d1
Out[48]:
{1: [1, 2],
 2: [1, 2],
 3: [1, 2],
 4: [1, 2],
 5: [1, 2],
 6: [1, 2],
 7: [1, 2],
 8: [1, 2],
 9: [1, 2],
 10: [1, 2]}
In [49]: d1[10].append(3)
In [50]: d1
Out[50]:
{1: [1, 2, 3],
 2: [1, 2, 3],
 3: [1, 2, 3],
 4: [1, 2, 3],
 5: [1, 2, 3],
 6: [1, 2, 3],
 7: [1, 2, 3],
 8: [1, 2, 3],
 9: [1, 2, 3],
 10: [1, 2, 3]}

字典元素的访问

  • d[key]
    返回key对应的值value
    key 不存在抛出KeyError异常

  • get(key[,default])
    返回key对应的值value
    key不存在返回缺省值,如果没有设置缺省值就返回None

  • setdefault(key[,default])
    返回key对应的值value
    key不存在,添加kv对,value为default,并返回default,如果default没有设置,缺省为None
In [51]: d2 = dict(([(1,3,4),{1,2,3,4,5,6}],))
In [52]: d2
Out[52]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}}
In [53]: d2[(1,3,4)]
Out[53]: {1, 2, 3, 4, 5, 6}
In [54]: f = d2.get((1,3,4))
In [55]: f
Out[55]: {1, 2, 3, 4, 5, 6}
In [56]: type(f)
Out[56]: set
#如果不存在,则返回
In [57]: d2.get(1,50)
Out[57]: 50
# 如果存在,则返回
In [59]: d2.get((1,3,4),50)
Out[59]: {1, 2, 3, 4, 5, 6}
In [60]: f = d2.setdefault(4,400)
In [61]: f
Out[61]: 400
In [62]: d2
Out[62]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}, 4: 400}

字典增加和修改

  • d[key] = value
    将key对应的值修改为value
    key 不存在添加新的kv对
  • update([other]) -> None
    使用一个字典的kv对更新本字典
    key不存在,就添加
    key存在,覆盖已经存在的key对应的值
    就地修改
 d.upadte(red=1)
 d.update((('red',2),))
 d.update({'red':3})
 In [63]: d2[100] = 100
In [64]: d2
Out[64]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}, 4: 400, 100: 100}
In [67]: d2
Out[67]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}, 4: 300, 100: 100}
In [68]: d3 = {100:1000, 5:'abc'}
In [69]: d3
Out[69]: {100: 1000, 5: 'abc'}
In [70]: d2.update(d3,red =1)
In [71]: d2
Out[71]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}, 4: 300, 100: 1000, 5: 'abc', 'red': 1}

字典删除

  • pop(key[,default])
    key 存在,移除它,并返回它的value
    key 不存在,返回给定的default
    default未设置,key不存在则抛出KeyError异常
  • popitem()
    移除并返回一个任意的键值对
    字典为empty,抛出KeyError异常

  • clear()
    清空字典

字典删除

del语句

In [72]: a = True
In [73]: b = [6]
In [76]: d = {'a':1,'b':b,'c':[1,3,5]}
In [77]: del a
In [78]: a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-78-3f786850e387> in <module>()
----> 1 a
NameError: name 'a' is not defined
In [79]: del d['c']
In [80]: d
Out[80]: {'a': 1, 'b': [6]}
In [81]: del b
In [82]: d
Out[82]: {'a': 1, 'b': [6]}
In [84]: del d['b']
In [85]: d
Out[85]: {'a': 1}
# del d['b'] 看着像删除了一个对象,本质上减少了一个对象引用,del实际上删除的是名称,而不是对象

字典遍历

默认打印的是keys

In [86]: d2
Out[86]: {(1, 3, 4): {1, 2, 3, 4, 5, 6}, 4: 300, 100: 1000, 5: 'abc', 'red': 1}
In [87]: for item in d2:
    ...:     print(item)
    ...:
(1, 3, 4)
4
100
5
red

打印value 和key

In [89]: for item in d2.values():
    ...:     print(item)
    ...:
{1, 2, 3, 4, 5, 6}
300
1000
abc
1
In [90]: for item in d2.keys():
    ...:     print(item)
    ...:
(1, 3, 4)
4
100
5
red

字典解构

In [92]: for k,b in d2.items():
    ...:     print(k,b)
    ...:
(1, 3, 4) {1, 2, 3, 4, 5, 6}
4 300
100 1000
5 abc
red 1

#只取key的情况
In [91]: for k,_ in d2.items():
    ...:     print(k)
    ...:
(1, 3, 4)
4
100
5
red

总结

  • Python3 中 ,keys、values、 items()方法返回一个类似一个生器的可迭代对象,不会把函数的反回结果复制到内存中
  • Python2 中,上面的方法会返回一个新的列表,占据新的内存空间,所以Python2 建议使用iterkeys、itervalues版本,返回一个迭代器,而不是一个copy

标准库datetime

  • datetime模块
    对日期、时间 、时间戳的处理

  • datetime类
    类方法
    today() 返回本地时区当前时间的datetime对象
    now(tz=None)返回当前时间的datetime对象,时间到微秒,如果tz为None,返回和today()一样
    utcnow() 没有时区的当前时间
    fromtimestamp(timestamp,tz=None)从一个时间戳返回一个datetime对象

  • datetime对象
    timestamp()返回一个到微秒的时间戳
    时间戳:格林威治时间1970年1月1日0点到现在秒数
In [2]: datetime.datetime.now()
Out[2]: datetime.datetime(2020, 7, 30, 21, 3, 4, 140745)
In [3]: datetime.datetime.now().timestamp()
Out[3]: 1596114189.706269

标准库datetime

构造方法 datetime.datetime(2016,12,6,16,29,43,79043)
year、 month、 day、hour、minute、 second、 microsecond,取datetime对象的年月日时分秒及微秒
weekday() 返回星期的天,周一0,周日6
isoweekday()返回星期的天,周一1,周日7
date()返回日期date对象
time()返回时间time对象
repliace()修改并返回新的时间
isocalendar()返回一个三元组(年,周数,周的天)

In [2]: datetime.datetime.now()
Out[2]: datetime.datetime(2020, 7, 30, 21, 3, 4, 140745)
In [3]: datetime.datetime.now().timestamp()
Out[3]: 1596114189.706269
In [4]: a = datetime.datetime.now()
In [5]: a
Out[5]: datetime.datetime(2020, 7, 30, 21, 14, 47, 500215)
In [6]: a.weekday()
Out[6]: 3

标准库datetime

  • 日期格式化
    类方法strptime(date_string,format),返回datetime对象
    对象方法strftime(format),返回字符串
    字符串format函数格式化
In [16]: dt = datetime.datetime.now()
In [17]: dt = dt.strftime('%Y-%m-%d-%H-%M-%S')
In [18]: dt
Out[18]: '2020-07-30-21-21-39'

利用format 格式化

In [26]: a = datetime.datetime.now()
In [27]: '{}-{}-{}-{}-{}-{}'.format(a.year,a.month,a.day,a.hour,a.minute,a.second)
Out[27]: '2020-7-30-21-27-33'

标准库datetime

  • timedelta对象
    datetime2 = datetime1 + timedelta
    datetime2 = datetime1 - timedelta
    timedelta = datetime1 - datetime2

  • 构造方法

datetime.timedelta(days=0,seconds=0,microseconds=0,milliseconds=0,minutes=0,hours=0,weeks=0)

year = datetime.timedelta(days=365)
total_seconds()返回时间差的总秒数

In [36]: h
Out[36]: datetime.timedelta(days=1)
In [37]: h = datetime.timedelta(hours=24)
In [38]: h
Out[38]: datetime.timedelta(days=1)
In [39]: datetime.datetime.now() - h
Out[39]: datetime.datetime(2020, 7, 29, 21, 37, 6, 827493)

标准库time

将调用的线程挂起指定的秒数 ~

In [40]: import time
In [41]: time.sleep(1)

列表解析List

  • 语法
    [返回值for 元素 in 可迭代对象 if 条件]
    使用中括号[],内部是for循环,if条件语句可选
    返回一个新的列表

  • 列表解析式是一种语法糖
    编译器会优化,不会为简写而影响效率,反而因优化提交了效率;
    减少程序员工作量,减少出错;
    简化了代码,但可读性增强

In [9]: newlist1 = [(i+1)**2 for i in range(10)]
In [10]: newlist1
Out[10]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

举例1、获取10以内的偶数,比较执行效率

even = []
In [11]: even = []
In [12]: for x in range(10):
    ...:     if x % 2 == 0:
    ...:         even.append(x)
In [13]: even
Out[13]: [0, 2, 4, 6, 8]
In [15]: even = [ x for x in range(10) if x%2 ==0]
In [16]: even
Out[16]: [0, 2, 4, 6, 8]

举例三种输出结果

In [19]: list1 = [(i,j)for i in range(7) if i>4 for j in range(20,25) if j>23]
In [20]: list1
Out[20]: [(5, 24), (6, 24)]
In [23]: list2 = [(i,j) for i in range(7) for j in range(20,25) if i>4 if j>23]
In [24]: list2
Out[24]: [(5, 24), (6, 24)]
In [28]: list3 = [(i,j) for i in range(7) for j in range(20,25) if i>4 and j>23]
    ...:
In [29]: list3
Out[29]: [(5, 24), (6, 24)]

练习,生成1-10 平方的列表

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

练习,有一个列表lst = [1,4,9,16,2,5,10,15],生成一个新列表,要求新列表元素是lst想领2项的和

In [34]: lst = [1,4,9,16,2,5,10,15]
In [35]: [ lst[i] + lst[i+1] for i in range(len(lst)-1)]
Out[35]: [5, 13, 25, 18, 7, 15, 25]
In [44]: lst = [1,4,9,16,2,5,10,15]
In [45]: for i in range(len(lst)-1):
    ...:     newlist= lst[i] + lst[i+1]
    ...:     print(newlist)
    ...:
5
13
25
18
7
15
25

用一行代码打印9 9乘法表

In [56]: print('\n'.join([''.join(['{}*{}={}\t'.format(x,y,y*x) for x in range(1,y+1)]) for y in range(1,10)]))
1*1=1
1*2=2    2*2=4
1*3=3    2*3=6    3*3=9
1*4=4    2*4=8    3*4=12    4*4=16
1*5=5    2*5=10    3*5=15    4*5=20    5*5=25
1*6=6    2*6=12    3*6=18    4*6=24    5*6=30    6*6=36
1*7=7    2*7=14    3*7=21    4*7=28    5*7=35    6*7=42    7*7=49
1*8=8    2*8=16    3*8=24    4*8=32    5*8=40    6*8=48    7*8=56    8*8=64
1*9=9    2*9=18    3*9=27    4*9=36    5*9=45    6*9=54    7*9=63    8*9=72    9*9=81

高效方法二

In [86]: print(''.join(['{}*{}={:<3}{}'.format(j,i,i*j,'\n' if i==j else'') for i in range(1,10) for j in range(1,i+1)]))
1*1=1
1*2=2  2*2=4
1*3=3  2*3=6  3*3=9
1*4=4  2*4=8  3*4=12 4*4=16
1*5=5  2*5=10 3*5=15 4*5=20 5*5=25
1*6=6  2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7  2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8  2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9  2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81

练习

“0001.abadicddws” 是ID格式,要求ID格式是以点号分割, 左夯实是4位从1开始的整数,右边是10位随机小写英文字母。今次生成前100个列表

In [100]: ['{:04}.{}'.format(n,''.join([random.choice(bytes(range(97,123)).decode()) for _ in range(10)])) for n in range(1,101)]
Out[100]:
['0001.yibbcfebfn',
 '0002.wvomuwuiaj',
 '0003.bplvnhkgfp',
 '0004.tnrjwiuipv',
...

生成器表达式(Generator expression)

  • 语法
    (返回值for 元素 in 可迭代对象if条件)
    列表解析式的中括号抱成小括号就行了
    返回一个生成器
  • 和列表解析式的区别
    生成器表达式是按按需计算(或称惰性求值、延迟计算),需要的时候才计算值
    列表解析式是立即返回值
  • 生成器
    可迭代对象
    迭代器

生成器表达式

  • 和列表解析式的对比
    计算方式
    生成器表达式延迟计算,列表解析式立即计算

  • 内存占用
    单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
    生成器没有数据,内存占用少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多
    列表解析式构造新的列表需要占用内存

  • 计算速度
    单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长
    但是生成器本身并没有返回任何值,只返回了一个生成器对象
    列表解析式构造并返回了一个新的列表

集合解析式

  • 语法
    (返回值 for 元素 in 可迭代对象 if 条件)
    列表解析式的中括号换成大括号{}就行了
    立即返回一个集合

  • 用法

{(x,x+1) for x in range(10)}
{{x} for x in range(10)}

字典解析式

  • 语法
    (返回值 for 元素in可迭代对象if条件)
    列表解析式的中括号换成大括号{}就可行了
    使用key:value 形势
    立即返回一个字典

  • 用法

{x:(x,x+1) for x in range(10)}
{x:[x,x+1] for x in range(10)}
{(x,):[x,x+1] for x in range(10)}
{[x]:[x,x+1] for x in range(10)}
{chr(0x41+1):x**2 for x in range(10)}
{str(x):y for x in range(3) for y in range(4)}
In [3]: {chr(0x41+x):x**2 for x in range(5)}
Out[3]: {'A': 0, 'B': 1, 'C': 4, 'D': 9, 'E': 16}
In [4]: {str(x):y for x in range(3) for y in range(4)}
Out[4]: {'0': 3, '1': 3, '2': 3}
# 等价于
In [13]: ret = {}
In [14]: for x in range(3):
    ...:     for y in range(4):
    ...:         ret[str(x)] = y
    ...:
In [15]: print(ret)
{'0': 3, '1': 3, '2': 3}

总结

  • Python2 引入了列表解析式
  • Python2.4引入了生成器表达式
  • Python3 引入集合、字典解析式,并迁移到了2.7
  • 一般来说,应该多应用解析式,简短、高效
  • 如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环
  • 生成器和迭代器是不同的对象,但都是可迭代对象。

内建函数

  • 标识 id
    返回对象的唯一标识,CPython 返回内存中

  • 类型hash()

返回一个对象的哈希值

  • 类型type()

返回对象的类型

  • 类型转换

float() int() bin() hex() oct() bool() list() tuple() dict() set() complex() bytes() bytearray()

  • 输入input([prompt])

接收用户输入,返回一个字符串

  • 打印 print(*objects, sep=’’,end=’\n’,file=sys.stdout, flush=False)

打印输出,默认使用空格分割、换行结尾,输出到控制台

  • 对象长度len(s)

返回一个集合类型的元素个数

  • isinstance(obj,class_or_tuple)

判断对象obj是否属于某种类型或者元组中列出的某个类型
isinstance(True,init)

  • issubclass(cls,calss_or_tuple)

判断类型cls是否是某种类型的了类或元组中列出的某个类型的子类
issubclass(bool,int)

  • 绝对值abs(x) x 为数值
  • 最大值max() 最小值min()
    返回可迭代对象中最大或最小值
    返回多个参数中最大或最小值
  • round(x) 四舍六入五取偶, round(-0.5)
  • pow(x,y) 等价于x**y
  • range(stop)从0开始到stop-1 的可迭代对象; range(start,stop,[,step]) 从start开始到stop-1 结束步长为step 的可迭代对象

  • divmod(x,y) 等价于tuple(x//y,x%y)

  • sum(oterable[,start])对可迭代对象的所有数值元素求和
    sum(range(1,100,2))

补充列表全部拷贝

In [17]: lst = [1,2,3]
In [18]: test = lst[:]
In [19]: test
Out[19]: [1, 2, 3]

python 求一到100的和

In [20]: sum(range(1,101))
Out[20]: 5050
  • chr(i) 给一个一定范围的整数返回对应的字符
    chr(97) chr(20013)

  • ord(c) 返回字符对应的整数

ord(‘a’) ord(‘中’)

  • str() 、 repr()、 ascii()

  • sorted(iterable)

  • sorted(iterable[,key][,reverse])排序
    返回一个新的列表,默认升序
    reverse 是反转

sorted([1,3,5])
sorted([1,3,5], reverse=True)
sorted({'c':1, 'b':2, 'a':1})
In [5]: lst = [1,4,3,5,8,7]
In [6]: sorted(lst)
Out[6]: [1, 3, 4, 5, 7, 8]
In [7]: sorted(lst,reverse=True)
Out[7]: [8, 7, 5, 4, 3, 1]

翻转 reversed(seq)
返回一个翻转元素的迭代器

list(reversed(*13579*))
for x in reversed(["c","b","c"]: )
In [13]: for k,v in enumerate(range(5)):
    ...:     print(k,v,end='\t')
    ...:
0 0    1 1    2 2    3 3    4 4
In [14]: for k,v in enumerate("mnopq",start=10):
    ...:     print(k,v,end='\t')
    ...:
10 m    11 n    12 o    13 p    14 q
  • 迭代器和取元素iter(terable)、next(iterator)
    iter 将一个可迭代对象封装成一个迭代器
    next对一个迭代器取下一个元素。如果全部元素都取过了,再次next会抛StopIteration异常
it = iter(range(5))
nex(it)
it = reversed([1, 3, 5])
next(it)

可迭代对象
能够通过迭代一次次返回不同的元素的对象。所谓相同不是指值是否相同。而元素在容器中是否是同一个,例如列表中值可以重复。
可以迭代,但是未必有序,未必可索引。
可迭代对象有: list、tuple、string、bytes、bytearray、range、set、dict、生成器等;
可以使用成员操作符in 、 not in,in本质上就是在遍历对象;

3 in range(10)
3 in (x for x in range(10))
3 in {x:y for x,y in zip(range(4),range(4,10))}

迭代器

特殊的对象,一定是可迭代对象,具备可迭代对象的特征;
通过iter方法把一个可迭代对象封闭成迭代器;
通过next 方法, 迭代 迭代器对象;
生成器对象,就是迭代器对象

In [1]: for x in iter(range(10)):
   ...:     print(x)
In [3]: g = (x for x in range(10))
In [4]: print(type(g))
<class 'generator'>
In [5]: print(next(g))
0
In [6]: print(next(g))
1
In [7]: print(next(g))
2
In [8]: print(next(g))
3
  • 拉链函数zip(*iterables)

像拉链一样,把多个可迭代对象合并在一起,返回一个迭代器
将每次从不同对象中取到的元素合并成一个元组

list(zip(range(10),range(10)))
list(zip(range(10),range(10),range(5),range(10)))
dict(zip(range(10),range(10)))
{str(x):y for x,y in zip(range(10),range(10))}

字典练习

打印每一位数字及期重复的次数

while True:
    num = input('Please input a positice intteger >>').strip()
    if num.isdigit():
        break
    else:
        print('Only digits are allowed! ')
record = {}
for i in num:
    record[i] = record.get(i,0) +1
print(num,record,sep='\n')

方法二

#!/usr/bin/env python
# -*- coding: utf-8 -*-
num = input('>> ')
d = {}
for c in num:
    if not d.get(c):
        d[c] = 1
        continue
    d[c] +=1
print(d)

d = {}
for c in num:
    if c not in d.keys():
        d[c] =1
    else:
        d[c] += 1
print(d)
>> 18933
{'1': 1, '8': 1, '9': 1, '3': 2}
{'1': 1, '8': 1, '9': 1, '3': 2}

字符串重复统计

字符表’abcdefghijklmnopqrstuvwxyz’
随机挑选2个字母组成字符串,共挑选100个
降序输出这100个字符串及重复的次数

import random
import string
strs = 'abcdefghijklmnopqrstuvwxyz'
dic = {}
for _ in range(100):
    randstr = ''.join(random.sample(strs,2))
    # randstr = ''.join(random.choice(strs) for _ in range(0,2))
    # randstr = ''.join(random.sample(string.ascii_lowercase,2))
    if randstr not in dic:
        dic.setdefault(randstr,1)
    else:
        dic[randstr] +=1
sortstr = sorted(dic.keys())
for i in sortstr:
    print('{:<4} {:<4}'.format(i,dic[i]))

评论