[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]))