本文是自己学习廖雪峰Python教程的笔记,记录些常用用法,方便以后找代码片段。

JfzPylib.py文件:

 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
#!/usr/bin/env python3
#coding=utf-8
'''
异想家Python函数库
'''
import math
# 求绝对值
def Fun_abs(x):
    if not isinstance(x, (int, float)): 
        raise TypeError('bad operand type') 
    if x>=0:
        return x
    else:
        return -x

# 解一元二次方程
def Fun_Solve2yuanEquation(a,b,c): 
    delta = b*b-4*a*c
    if delta < 0:
        return
    elif delta == 0:
        x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
        return x1
    else:
        x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
        x2 = (-b - math.sqrt(b*b-4*a*c))/(2*a)
        return x1,x2

JfzPyStudy.py文件:

   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
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
#!/usr/bin/env python3
# coding=utf-8
' 异想家Python学习 '
__author__ = 'Sandeepin'

# 【1】输出
print('\n\033[1;31m【1】输出\033[0m\n')
print("异想家")  # 双引号
print('Fuck''Bitch','Shit')  # 单引号,逗号间隔,输出变空格
print('1234 - 5678 =',1234-5678)  # 输出数字计算

# 【2】输入
print('\n\033[1;31m【2】输入\033[0m\n')
#name = input()
#print(name)
#name2 = input('输入网名')
#print(name2)

# 【3】Python基础
print('\n\033[1;31m【3】Python基础\033[0m\n')
# 缩进强迫写出格式化代码,坚持使用【4个空格】的缩进
# Python程序【大小写敏感】

# 【4】数据类型、变量
print('\n\033[1;31m【4】数据类型、变量\033[0m\n')
print(1024)
print(0xff)
print(1.23e9)
print('abc')
print("xyz")
print("x\'y\'z\n")  # 转义字符\n换行
print(r'\\\t\\')  # r表示内部字符不转义
print('''123
456
789''')  # '''括起的内容可多行
# True False and or not  # 布尔运算
# None  # 空值

a = 123  # 变量数值
print(a)
a = 'jfz'  # 变量字符串,同一变量反复赋值
b = a
a = '666'
print(a)
print(b)
PI = 3.14159265359  # 常量用大写表示,实际上是变量,想改就改
print(PI)
print(10 / 3)
print(10 // 3)  # 地板除,整数部分
print(10 % 3)  # 余数部分
# Python整数无大小限制,浮点数也没限制,太大会变成inf(无限大)

# ASCII 1个字节,Unicode 通常2个字节, UTF-8 可变长编码(英语1个,中文3个,特殊4-6个)
print('中文str')  # python字符串以Unicode编码
print(ord('A'))  # ord获取字符整数表示
print(ord('蒋'))
print(chr(66))   # ord编码整数转字符
print(chr(26041))
print('\u4e2d\u6587')  # 用16进制写中文
print(b'ABC')# 编码为bytes
print('ABC'.encode('ascii'))
print('异想家123'.encode('utf-8'))
print(b'fuck'.decode('ascii'))# 解码为str
print(b'\xe8\x92\x8b\xe6\x96\xb9\xe6\xad\xa3'.decode('utf-8'))

print(len('ABC'))  # 计算str字符数
print(len('异想'))
print(len(b'ABCddd'))  # 计算bytes字节数

# 【5】格式化输出
print('\n\033[1;31m【5】格式化输出\033[0m\n')
# 和C语言类似,%d %f %s %x
print('Jfz %d poi %s' %(77, 'sandeepin') )  # 几个%号,在后面就用%(1,2)填几个
print('%02d %07.3f' %(7, 33.3333333333) )  # 补零,类似C语言
print('年龄: %s %% 男士: %s' %(23, True) )  # %s永远起作用,不知道用什么的时候用它, %%转义%
s1 = 72
s2 = 85
r = s1/s2
print('比率s1/s2 = %.2f' % r)
print('彩色显示:\033[1;31mSandeepin\033[0m')

# 【6】list列表
print('\n\033[1;31m【6】list列表\033[0m\n')
# list列表是可变有序集合,用xxx = ['1','2','3']表示
classmates = ['Sandeepin', 'Samothrace', 'Bitch']
print(classmates)
print(len(classmates))  # list元素个数
print(classmates[0])  # 类似数组下标的方式访问元素,从0开始
print(classmates[2])
print(classmates[-1])  # 倒数第一个,即classmates[2]
print(classmates[-2])  # 倒数第二个
classmates.append('Jfz')  # 追加元素
classmates.insert(1,'poi')  # 插入元素,插在第1个(下标从0开始)
print(classmates)
classmates.pop()  # 弹出,最后一个元素删除
print(classmates)
classmates.pop(2)  # 弹出下标为2的那个
print(classmates)
classmates[0] = 'jiangfangzheng'  # 替换用赋值方法
print(classmates)
mixlist = ['poi',123,3.5678,['www','jj']]  # list元素类型可混合,list套list
print(mixlist[3][1])  # 相当于二维数组
nonelist=[]
print(len(nonelist))  # 空list

# 【7】tuple元组
print('\n\033[1;31m【7】tuple元组\033[0m\n')
# tuple元组是有序列表,类似list,但是tuple初始化后不能改,用xxx = ('1','2','3')表示
classmates = ('Michael', 'Bob', 'Tracy')
print(classmates)
print(classmates[1])
t = (1,)  # 只有一个元素的tuple要加个逗号,避免歧义为赋值1
print(t)  # 显示时也会加逗号防止误解
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
print(t)  # tuple元素不变,里面有list,list元素可变

# 【8】条件判断
print('\n\033[1;31m【8】条件判断\033[0m\n')
age = 19
if age >= 18:
    print('成年人')  # 从上往下判断,符合要求后剩下的判断忽略
elif age>=6:
    print('青少年')
else:
    print('小孩')
x =3
if x:
    print('True')   # 简写,x非0,非空就为True

#year = input()
##if year > 2000:         # 输入1999程序出错,因为输入的是字符串,要转成整数
#if int(year) > 2000:     # int()函数转整数
#    print('2000年之后')
#else:
#    print('2000年之前')

#print('体重判断程序')
#height = input('输入身高')
#weight = input('输入体重')
#bmi = int(weight)/(int(height)*int(height))
#if bmi>25:
#    pass  # pass跳过,不填报错
#else:
#    print('不胖')

# 【9】循坏
print('\n\033[1;31m【9】循坏\033[0m\n')
# 第1种 for...in循坏
names = ['异想家','sandeepin','jfz']
for aaa in names:  # 就是把每个元素带入aaa,执行下面语句一回
    print(aaa)
# 求和举例
qiuhe = 0
for x in [1,2,3,4,5,6,7,8,9,10]:
    qiuhe = qiuhe + x
print(qiuhe)

qiuhe = 0
for x in range(11):  # 生成从0开始的小于11的数的list
    qiuhe = qiuhe + x
print(qiuhe)

# 第2种 while循坏
n = 10
qiuhe = 0
while n > 0:
    qiuhe = qiuhe + n
    n = n -1
print(qiuhe)
# 【技巧】死循环时按Ctrl + C 强制退出

# 【10】字典
print('\n\033[1;31m【10】字典\033[0m\n')
# 字典dictionary类似其它语言中的map,键-值存储,快速查找,其内部存放顺序与放入顺序无关
# 字典以空间(内存)换时间,list以时间换空间,dictionary适合高速场合
# 字典的Key不能变,因此不能以list作为Key
jfzn = {'jfz':100,'sandeepin':96,'poi':88}
print(jfzn['poi'])  # 就像给数组的下标起别名,访问对应数值
jfzn['jfz'] = 99  # 字典内容赋值
print(jfzn['jfz'])
print('Thomas' in jfzn)  # 判断Key是否在字典中
print(jfzn.get('Thomas'))  # 不在返回None
print(jfzn.get('Thomas', 999))  # 不在返回自定义的999
print(jfzn.pop('poi'))  # 弹出Key
print(jfzn)

# set类似字典dict,是Key的集合,可作交并计算,不储存value
s = set([1, 2, 3])  # list作为输入
ss = set([1,1,2,2,3,3])  # 滤除重复元素
print(s)
s.add(4)  # 添加Key,重复无用
s.remove(1)  # 移除Key
print(s)
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
print(s1 & s2)  # 交运算
print(s1 | s2)

# 【11】可变与不可变学习
print('\n\033[1;31m【11】可变与不可变学习\033[0m\n')
# list可变
abc = ['b','a','c']
abc.sort()  # 排序
print(abc)
# str不可变
strabc = 'bac'
print(strabc.replace('b','B'))  # 替换只对当前有效,strabc本质没变
print(strabc)

# 【12】函数
print('\n\033[1;31m【12】函数\033[0m\n')
# 调用函数 help(abs) 查看abs函数信息,官网看文档 http://docs.python.org/3/library/functions.html#abs
print(abs(-5))
print(max(2, 3, 1, -5))
# 数据类型转换函数
print(int('123'))
print(int(12.3))
print(float(123.456))
print(bool(1))
# 函数名本身就是一个引用,完全可以给函数名取别名
ShiLiu = hex
print(ShiLiu(12))
# 自定义函数
def Fun_SanCiFang(x):
    return x*x*x
print(Fun_SanCiFang(3))  # 调用函数
from JfzPylib import Fun_abs  # 从JfzPylib.py文件中导入函数Fun_abs
print(Fun_abs(-93))
# 返回多个值
import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

print(move(10, 20, 50))  # 返回的本质是一个元组
x, y = move(10, 20, 50)  # 返回一个元组可省略括号
print(x, y)

def Fun_Solve2yuanEquation(a,b,c):  # 解二次方程函数
    delta = b*b-4*a*c
    if delta < 0:
        return
    elif delta == 0:
        x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
        return x1
    else:
        x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
        x2 = (-b - math.sqrt(b*b-4*a*c))/(2*a)
        return x1,x2
print(Fun_Solve2yuanEquation(1,4,7774))
# 函数参数——默认参数、可变参数、关键字参数
def CiFang(x):
    return x*x
print(CiFang(2))
def LiFang(x):
    return x*x*x
print(LiFang(2))
# 位置参数,顺序要定好,n=2是默认参数
def CiFangN(x, n=2):
    out = 1
    while n > 0:
        out = out * x
        n = n - 1
    return out
print(CiFangN(2,4))# 位置参数
print(CiFangN(2))  # 默认参数,必选参数在前,默认参数在后,否则有歧义
# 默认参数,变化大的放在前面,变化小的放在后面
def ZhuCe(name, gender , age=6, city = 'Guilin'):
    print('name=%s, gender=%d, age=%d, city=%s'%(name,gender,age,city))
    return 'OK'
print(ZhuCe('jfz', 2))
print(ZhuCe('poi', 1, 8))  # 按顺序补全
print(ZhuCe('poi', 1, city='wuhan'))  # 选择输入city,其它默认
# 一个坑
def add_end(L=[]):
    L.append('END')
    return L
poid=[3,2,1]
print(add_end(poid))
print(add_end())
print(add_end())  # 输出了['END', 'END'],默认参数L被记着了,不能这么用
# 正确写法:
def add_endfix(L=None):
    if L is None:
        L=[]
    else:
        L.append('END')
    return L
print(add_endfix())
print(add_end())
# 【技巧】能设计为不变对象时,就尽量设计成不变对象,防止意外修改

# 可变参数——传入的参数可变
# 传统方法:传list或tuple
def calcX2(shuru):
    sum = 0
    for fuck in shuru:
        sum = fuck*fuck +sum
    return sum
fuckk=[1,2,3]
print('calcX2 =',calcX2(fuckk))
# 可变参数法——仅在参数前加个*号
def calcX2B(*shuru):
    sum = 0
    for fuck in shuru:
        sum = fuck*fuck +sum
    return sum
print('calcX2B =',calcX2B(fuckk[0], fuckk[1], fuckk[2]))  # 输入参方法1
print('calcX2B =',calcX2B(*fuckk))  # 输入参方法2
print('calcX2B =',calcX2B(1, 2, 3))  # 输入参方法3

# 关键字参数——加两个**,扩展函数功能,获得额外信息
def ZhuCeKW(name, gender , **kw):
    print('name=%s, gender=%d other='%(name, gender), kw)
    return 'OK'
print(ZhuCeKW('duck', 3))
print(ZhuCeKW('duck', 3, city='wuhan'))
extra = {'age':12, 'city':'guilin'}  # 键值形式输入
print(ZhuCeKW('duck', 3, **extra))  # extra加**
# 限制关键字参数——命名关键字参数
# 例如只接受city和age
# 命名关键字参数以特殊的单个*表示,后面的为命名关键字参数
# 命名关键字参数必须传入参数名
def ZhuCeCheck(name, gender, *, age, city='guilin'):
     print(name, gender, age, city)
     return 'OK'
print(ZhuCeCheck('Jack', 24, city='Beijing', age = 11))
# print(ZhuCeCheck('Jack', 24, city='Beijing', job='Engineer'))  # 输出出错

# 参数组合举例——必选、默认、可变、关键字、命名关键字
# 顺序: 必选、默认、可变\关键字\命名关键字
# 可变和命名显然不能混在一起
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
f1(1, 2)
f1(1, 2, c=3)
f1(1, 2, 3, 'a', 'b')  # a、b是可变
f1(1, 2, 3, 'a', 'b', x=99)  # x=99是关键字,用 = 表示键值配对
f2(1, 2, d=99, ext=None)   # d为命名关键字,只有写d=xx才对,**kw就换成关键字了,变成键值配对
args = (1, 2, 3, 4)  # 通过tuple和dict作为输入
kw = {'d': 99, 'x': '#'}
f1(*args, **kw)  # 任意函数都可以以形式f1(*args, **kw)调用
args = (1, 2, 3)
kw = {'d': 88, 'x': '#'}
f2(*args, **kw)
# 【小结】
# *args是可变参数,接收tuple元组
# **kw是关键字参数,接收dict字典
# func(1,2,3)可以装list、tuple通过*args传入func(*(1,2,3))
# func(a=1,b=2),可以装dict通过**kw传入func(**{'a':1,'b':2})

# 【13】递归函数——函数调用本身
print('\n\033[1;31m【13】递归函数\033[0m\n')
def JieCheng(n):
    if n == 1:
        return 1
    else:
        return n * JieCheng(n-1)
print('递归阶乘:', JieCheng(5))
# 递归太多层会栈溢出,解决方法:尾递归优化
# 常规递归过程如下:
# ===> fact(5)
# ===> 5 * fact(4)
# ===> 5 * (4 * fact(3))
# ===> 5 * (4 * (3 * fact(2)))
# ===> 5 * (4 * (3 * (2 * fact(1))))
# ===> 5 * (4 * (3 * (2 * 1)))
# ===> 5 * (4 * (3 * 2))
# ===> 5 * (4 * 6)
# ===> 5 * 24
# ===> 120
def fact(n):
  return fact_iter(n, 1)
def fact_iter(num, product):
  if num == 1:
    return product
  return fact_iter(num - 1, num * product)
print('优化阶乘:', fact(5))
# 优化递归过程如下:
# ===> fact_iter(5, 1)
# ===> fact_iter(4, 5)
# ===> fact_iter(3, 20)
# ===> fact_iter(2, 60)
# ===> fact_iter(1, 120)
# ===> 120
# 【遗憾的是】python没对尾递归优化,这样写照样爆栈

# 利用递归函数移动汉诺塔:
def move(n, a, b, c):
    if n == 1:
        print('move', a, '-->', c)
        return
    move(n-1, a, c, b)
    print('move', a, '-->', c)
    move(n-1, b, a, c)
move(3, 'A', 'B', 'C')  # n为A盘数量1

# 【14】高级特性
print('\n\033[1;31m【14】高级特性\033[0m\n')
# 传统的循坏实现 1 3 5 7 9
L = []
n = 1
while n <= 99:
    L.append(n)
    n = n + 2
print(L)

print('\n【1、切片Slice】')
# 切片Slice
L = ['Fuck','Bitch','Shit','Porn']
LL = [L[0],L[1],L[2]]  # 笨办法
print(LL)
LL = []
for n in range(2):   # 循环办法
    LL.append(L[n])
print(LL)
LLL = L[0:3]    # 切片办法,代表取0 1 2号元素
LLL = L[:3]     # 切片办法,0开始取可省略0
LLL = L[1:4]    # 切片办法,1 2 3
LLL = L[-2:-1]  # 切片办法,取倒数第二个2到倒数第1个(不包括倒数第1个)
LLL = L[-2:]    # 包括倒数第1个
print(LLL)
# 各种取法
L = list(range(100))
print(L)
LL = L[:10]
print(LL)
LL = L[-10:]
print(LL)
LL = L[0:10:2]  # 取0~10,隔2-1=1个取一个(第一个必取,从第一个开始,2个中取一个)
print(LL)
LL = L[::5]  # 全取,每5个取一个
print(LL)
LL = L[:]  # 全取,等于复制
print(LL)
T = (1,2,3,4,5)
TT = T[2:4]  # Tuple也可切片(1,2,3)[:3]类似形式
print(TT)
Str1 = 'abcdefg'
Str2 = Str1[0:3]  # 字符串也可切片
print(Str2)
# 【总结】切片可以节省循环,一句话实现

# 【迭代Iteration】
print('\n【2、迭代Iteration】')
# for循环遍历一遍就是迭代
# Python的for是高度抽象的循环
Fuck = {'Bitch':'Good','Porn':'OK','Shit':'No'}
for key in Fuck:  # 默认迭代key
    print(key)
for value in Fuck.values():  # 迭代value
    print(value)
for item in Fuck.items():  # 迭代key和value
    print(item)
for ch in 'Sandeepin':  # 字符串迭代
    print(ch)
# 判断一个对象是否能迭代
from collections import Iterable
print(isinstance('abc', Iterable))   # str可以
print(isinstance(123, Iterable))     # 整数不行
# 对list实现类似Java的下标循环
for i, value in enumerate(['A', 'B', 'C']):
    print(i,value)
for x, y in [(1, 1), (2, 4), (3, 9)]:  # 实现for循环引用两个变量
    print(x, y)

# 【列表生成式List Comprehensions】
print('\n【3、列表生成式List Comprehensions】')
# 用来创建list的生成式
# 生成 1 2 3 ... 10
print(list(range(1, 11)))
L = []
# 生成 1 4 9 ... 100
for x in range(1, 11):
    L.append(x * x)
print(L)
# 列表生成式的方法,生成 1 4 9 ... 100
LLL = [x * x for x in range(1, 11)]  # 生成结果 for 序号 in 序列
print(LLL)
# 后面能加 if 条件,例如只生成偶数的平方结果
LLL2 = [x * x for x in range(1, 11) if x%2 is 0]  # 生成结果 for 序号 in 序列
print(LLL2)
# 还可以两层、多层循环,实现全排列
LL = [m+n for m in 'ABC' for n in 'xyz']
print(LL)
# 字典键值同时迭代
for key,value in Fuck.items():  # 迭代key和value
    print(key,'=',value)
# 利用两个变量生成list
d = {'x': 'A', 'y': 'B', 'z': 'C' }
dd = [k + '=' + v for k, v in d.items()]
# list元素变小写
L = ['Hello', 'World', 'IBM', 'Apple']
L = [s.lower() for s in L]
print(L)
# 列出当前文件夹所有文件和目录
import os  # 导入OS模块
dirr = [d for d in os.listdir('.')]  # os.listdir列出当前文件夹所有文件和目录
print(dirr)
# 混合整型字符串的list转小写
L = ['Hello', 'World', 18, 'Apple', None]
S = [ss.lower() for ss in L if isinstance(ss, str)]  # 判断是否为字符串
print(S)

# 【生成器Generator】
print('\n【4、生成器Generator】')
# 列表生成式生成List受内存限制,很浪费空间。生成器在循环过程中不断推出后续元素,不必创建大量list,节省空间。
# 创建生成器Generator方法1:列表生成式[]改为()
g = (x * x for x in range(10))
print(next(g))
print(next(g))
print(next(g))  # 用next方法打印生成器

for n in g:    # 用for打印
    print(n)
# 复杂情况for循环实现不了的时候用函数实现,就需要生成器了
# Fibonacci数列 1, 1, 2, 3, 5, 8, 13, 21, 34
def FibonacciNum(num):
    n, a, b = 0, 0, 1
    while n < num:
        print(b)
        c = b
        b = a + b
        a = c
        # a, b = b, a + b  # 同时进行,可以省去一个变量
        n = n + 1
    return 'poi'
FibonacciNum(10)
# 递归实现Fibonacci数列
def FibonacciNumDigui(num):
    if num == 1:
        return 1
    elif num == 2:
        return 1
    else:
        out = FibonacciNumDigui(num - 1) + FibonacciNumDigui(num - 2)
        return out
print(FibonacciNumDigui(8))

# 变成生成器,只需要把print变成yield
def FibonacciGenerator(max):
  n, a, b = 0, 0, 1
  while n < max:
    yield b
    a, b = b, a + b
    n = n + 1
  return 'ppp'
# 变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
fg = FibonacciGenerator(6)
print(next(fg))  # 在执行过程中,遇到yield就中断,下次又继续执行
print(next(fg))
print(next(fg))
print(next(fg))
print(next(fg))
print(next(fg))
for n in FibonacciGenerator(6):  # for循坏调用生成器,基本上不用next
    print(n)  # 但是拿不到return的值,要用StopIteration,以后再说

# 杨辉三角形生成[jfz写,不完善]
def YangTriangles(num):
    if num == 1:
        a = [1,]
        #print(a)
        return a
    if num == 2:
        a = [1,1]
        #print(a)
        return a
    if num >=3:
        c = list(range(num))
        c[0] = 1
        c[-1] = 1
        for i in range(1,num-1):
            c[i] = YangTriangles(num-1)[i-1] + YangTriangles(num-1)[i]
        return c
print(YangTriangles(6))

# 【迭代器Iterable】
print('\n【5、迭代器Iterable】')
# 可以直接作用于for循环的对象统称为可迭代对象:Iterable: list、tuple、dict、set、str、generator
# 用isinstance()判断
from collections import Iterable
print('迭代对象:',isinstance((x for x in range(10)), Iterable))
print('迭代对象:',isinstance('1232',Iterable))  # 字符串可以
print('迭代对象:',isinstance(1232,Iterable))  # 数字不可以
# 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
from collections import Iterator
print('迭代器:',isinstance((x for x in range(10)), Iterator))
print('迭代器:',isinstance('1232',Iterator))
# 可迭代对象变迭代器:iter()
print('变迭代器:',isinstance(iter([]), Iterator))
print('变迭代器:',isinstance(iter('1232'),Iterator))
# Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。


# 【15】函数式编程
print('\n\033[1;31m【15】函数式编程\033[0m\n')
# Functional  Programming,函数式编程就是一种抽象程度很高的编程范式
# 函数式编程的一个特点: 允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
# 【高阶函数Higher-order function】

print('\n【1、高阶函数Higher-order function】')
absxxx = abs(-10)  # 变量指向函数返回值
print(absxxx)
absxx = abs  # 变量指向函数本身,函数名本身可看作一个变量,它指向具有某种作用的一个函数
print(absxx(-777))
# 一个函数接受另一个函数作为变量
def add(x, y, f):
    return f(x) + f(y)
print(add(-2, -3, abs))
# 把函数作为参数传入,这样的函数称为【高阶函数】

#【map/reduce】
# 有一个函数f(x)=x^2,要把这个函数作用在一个list[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现
fuck = [1,2,3,4,5,6]
def square2(x):
    return x * x
xxx = map(square2,fuck)  # 结果r是一个Iterator惰性序列
print(list(xxx))  # 用list算迭代器,计算出来
print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))  # 将数字字符串化

# reduce把一个函数作用在一个序列[x1, x2, x3, ...]上, 把结果继续和序列的下一个元素做累积计算
# 效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
def add(x, y):
    return x + y
print(reduce(add, [1, 2, 3, 4, 5]))  # 等于是求和,还可用sum
# 把序列[1, 3, 5, 7, 9]变换成整数13579
def fn(x, y):
    return x * 10 + y
print(reduce(fn, [1, 3, 5, 7, 9]))

# map/reduce配合,整理成一个str2int的函数
def str2int(s):
    def fn(x, y):
        return x * 10 + y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num, s))
print(str2int('123'))

# (jfz)实现输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']
def normalize(name):
    namelow = name.lower()  # 转小写
    return namelow.capitalize()  # 转首字母大写
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)

# (jfz)实现类似sum求和的求积函数prod()
def prod(L):
    def squareXxY(x, y):
        return x * y
    return reduce(squareXxY, L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))

# (jfz)实现str2float函数
def str2float(instr):
    def str2int(s):
        def fn(x, y):
            return x * 10 + y
        def char2num(s):
            return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
        return reduce(fn, map(char2num, s))
    [z, x]=instr.split('.')
    return str2int(z) + str2int(x)/(pow(10, len(x)))
print(str2float('123.456777'))

#【filter】
# filter()函数用于过滤序列
# 和map()类似,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
# 例如删掉偶数
def is_odd(n):
    return n % 2 == 1
print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])))
# 例如删掉空字符串
def not_empty(s):
    return s and s.strip()
print(list(filter(not_empty, ['A', '', 'B', None, 'C', '  '])))
# 【注意】filter()函数返回的是Iterator,也要list化

# 埃氏筛法用filter求素数
# 先构造一个从3开始的奇数序列:
def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n
# 定义一个筛选函数:
def _not_divisible(n):
    return lambda x: x % n > 0
# 定义一个生成器,不断返回下一个素数:
def primes():
    yield 2
    it = _odd_iter()  # 初始序列
    while True:
        n = next(it)  # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it)  # 构造新序列
# 调用时需要设置一个退出循环的条件:
# 打印1000以内的素数:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break
# (jfz)利用filter()滤掉非回文数:
print('回文数:')
def is_palindrome(n):
    strn = str(n)  # 转字符串
    i= len(strn)//2  # 半长度
    k = 0  # 回文计数
    for j in range(i):
        if strn[j] == strn[-(j+1)]:
            k = k + 1
    if k == i:# 回文次数=半长度说明回文
        return True
    else:
        return False
output = filter(is_palindrome, range(1, 1000))
print(list(output))

#【排序算法sorted】
# 排序的核心是比较两个元素的大小
# 数字直接比较,字符串或者两个dict呢?比较的过程必须通过函数抽象出来。
# 默认从小到大排list
print('从小到大排序:',sorted([36, 5, -12, 9, -21]))
# sorted()函数是高阶函数,可以接收一个key函数来实现自定义的排序
print('绝对值排序:',sorted([36, 5, -12, 9, -21],key=abs))
# 字符串排序,按ASCII的大小比较
print('字符串排序:',sorted(['bob', 'about', 'Zoo', 'Credit']))
# 按照字母序排序,忽略大小写
print('按字母排序(忽略大小写):',sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower))
# 反向排序,只需要传入第三个参数reverse=True
print('反向排序(从大到小):',sorted([36, 5, -12, 9, -21],reverse=True))
# 学生名字和成绩: 按名字排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
    tt = t[0]
    return tt
L2 = sorted(L, key=by_name)
print('按名字排序:',L2)
# 学生名字和成绩: 按成绩从高到低排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_score(t):
    tt = t[1]
    return tt
L2 = sorted(L, key=by_score, reverse=True)
print('按成绩排序:',L2)

# 返回函数
print('\n【2、返回函数】')
# 把函数作为结果值返回
# 通常求和的函数
def calc_sum(*args):
    ax = 0
    for n in args:
        ax = ax + n
    return a
print('直接求和:',calc_sum(1, 3, 5, 7, 9))
# 如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
# 定义的函数内部再定义一个函数,外函数返回内函数
print('延迟求和(返回求和函数):',lazy_sum(1, 3, 5, 7, 9))
# 当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力
# 当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print('闭包不等:',f1==f2)

# 【闭包】
# 返回的函数并没有立刻执行,而是直到调用了f()才执行
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs
f1, f2, f3 = count() # 将一个list中每个元素分别给f1, f2, f3
print('闭包调用才执行:', f1(), f2(), f3())  # 结果是9 9 9
# 原因就在于返回的函数引用了变量i,但它并非立刻执行。
# 等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9
# 【注意】返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量
# 如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值
def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs
f1, f2, f3 = count() # 将一个list中每个元素分别给f1, f2, f3
print('多一层函数:', f1(), f2(), f3())  # 结果是1 4 9

# 匿名函数
print('\n【3、匿名函数】')
# 就是没有名字的函数,关键字lambda表示匿名函数,冒号前面的x表示函数参数。
a = list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(a)
# 等于是:
def f(x):
    return x * x
a = list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(a)
# 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果
f = lambda x: x * x
print(f(5))
# 把匿名函数作为返回值返回
def build(x, y):
    return lambda:x*x+y*y
aaa = build(3, 4)
print(aaa())

# 装饰器
print('\n【4、装饰器】')
# 通过变量也能调用该函数
def jfz():
    print('poi')
sa = jfz
sa()
# 函数对象有一个__name__属性,可以拿到函数的名字
print(sa.__name__)
print(jfz.__name__)
# 假设要增强jfz()的功能,如在函数调用前后自动打印日志,但又不希望修改函数
# 这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)
# 本质上,decorator就是一个返回函数的高阶函数,定义如下函数:
def flog(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
kxy = flog(jfz)
kxy()
# 借助Python的@语法,把decorator置于函数的定义处:
@flog  # 调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志
def now():  # 相当于执行了语句:now = flog(now)
    print('fuck')
# 由于flog()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,
# 只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在flog()函数中返回的wrapper()函数
# 如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数
# 比如,要自定义flog的文本:
def flog(text):
    def decorator(func):  # 原来def flog(func)放到了内层,外层传文本text
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator
# 这个3层嵌套的decorator用法如下:
@flog('异想家')
def now():
    print('fuck')
now()  # 显示结果为:异想家 now():\n fuck; now()相当于 now = log('execute')(now)
# 经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper':
print(now.__name__)
# 需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错
# Python内置的functools.wraps就是干这个事的,一个完整的decorator的写法如下:
import functools
def flog(func):
    @functools.wraps(func)  # 最后一层函数时用functools.wraps
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
# 针对带参数的decorator:
def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

# (jfz)编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志
def belog(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('开始 %s()' % func.__name__)
        # f = func(*args, **kw)
        # print('结束 %s()' % func.__name__)
        # return f
        return [func(*args,**kw), print('结束 %s()' % func.__name__)][0]  # 网友的巧妙写法
    return wrapper
@belog
def now():
    print('fuck')
now()
print(now.__name__)

# (jfz)能否写出一个@log的decorator,使它既支持:
# @log
# def f():
#     pass
# 又支持:
# @log('execute')
# def f():
#     pass
def log(xxx):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    if isinstance(xxx,str):
        text = xxx
        return decorator
    else:
        text = '开始'
        return decorator(xxx)

@log
def lrz():
    print('路然真')
lrz()
print(lrz.__name__)

@log('姐姐')
def lrz():
    print('路然真')
lrz()
print(lrz.__name__)

# 偏函数Partial function
print('\n【5、偏函数Partial function】')
# 通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。
print('默认转十进制',int('12'))
print('自定义转八进制',int('12',base=8))
print('自定义转十六进制',int('12',16))
# 要转换大量的二进制字符串,定义一个int2()的函数,默认把base=2传进去:
def int2(x, base=2):
    return int(x, base)
# functools.partial就是帮助我们创建一个偏函数, 可以直接使用下面的代码创建一个新的函数int2:
import functools
intp2 = functools.partial(int, base=2)
print('偏函数转二进制',intp2('11111'))
# 【总结】functools.partial的作用就是把一个函数的某些参数给固定住,返回一个新的函数
# 也可以在函数调用时传入其他值:
print('偏函数转八进制',intp2('11', base=8))
# 创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数,当传入:
# int2 = functools.partial(int, base=2)相当于:
# kw = { 'base': 2 }
# int('10010', **kw)
max2 = functools.partial(max, 10)  # 把10作为*args的一部分自动加到左边
print('加了10的求最大',max2(5, 6, 7))  # 相当于:args = (10, 5, 6, 7);max(*args)

# 【16】模块Module
print('\n\033[1;31m【16】模块Module\033[0m\n')
# 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,一个.py文件就称之为一个模块Module
# 最大的好处是大大提高了代码的可维护性。
# 其次,编写代码不必从零开始。
# 使用模块还可以避免函数名和变量名冲突。
# Python的所有内置函数:https://docs.python.org/3/library/functions.html
# 例如:一个abc.py的文件就是一个名字叫abc的模块

# 如果不同的人编写的模块名相同怎么办?
# 为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)
# 方法是选择一个顶层包名,比如sandeepin,按照如下目录存放:
# -sandeepin
#    - abc.py
#    - jfz.py
# 现在,abc.py模块的名字就变成了sandeepin.abc
# 【注意】__init__.py文件必须存在,否则Python就把这个目录当成普通目录,而不是一个包。
# 类似的,可以有多级目录,组成多级层次的包结构。如fuck.bitch.shit
import sandeepin.poi.poilib
sandeepin.poi.poilib.poi()

# [使用模块]模板
# #!/usr/bin/env python3
# # -*- coding: utf-8 -*-
# ' a test module '
# __author__ = 'Sandeepin'
import sys
def test():
    # sys模块有一个argv变量,用list存储了命令行的所有参数。
    # argv至少有一个元素,因为第一个参数永远是该.py文件的名称
    # 运行python3 hello.py jfz获得的sys.argv就是['hello.py', 'jfz']
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')
# 当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__
# 如果在其他地方导入该hello模块时,if判断将失败
# 因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码
if __name__=='__main__':
    test()
# 启动Python交互环境,再导入hello模块, 没有打印Hello, word!,因为没有执行test()函数。

# [作用域]
# 在一个模块中,有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用
# 在Python中,是通过_前缀来实现,正常的函数和变量名是公开的(public),可以被直接引用
# 类似_xxx和__xxx这样的函数或变量就是非公开的(private),【不应该】被直接引用,比如_abc,__abc等
# private函数和变量不是【不能】被直接引用,是因为Python没有一种方法可以完全限制访问private函数或变量
def _private_1(name):
    return 'Hello, %s' % name
def _private_2(name):
    return 'Hi, %s' % name
def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)
# 我们在模块里公开greeting()函数,而把内部逻辑用private函数隐藏起来
# 【技巧】外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public
print(greeting('jfz'))
print(greeting('Sandeepin'))
print(_private_1('San'))  # 并不限制用
print(_private_2('sss'))

# [安装第三方模块]
# 在Python中,安装第三方模块,是通过包管理工具pip完成的
# 比如安装Pillow的命令就是:pip install Pillow

# 图片生成缩略图
from PIL import Image
def JfzBlogImgThumb(ImgName):
    im = Image.open(ImgName)
    print(im.format, im.size, im.mode)
    if max(im.size[0], im.size[1]) > 1000:
        if im.size[0] > im.size[1]:
            im.thumbnail((1280, 1280))
        else:
            im.thumbnail((1000, 1000))
        im.save('thumb\\'+ImgName, 'JPEG')
    return 'OK'
JfzBlogImgThumb('1.jpg')

最后附上廖雪峰的教程地址:https://www.liaoxuefeng.com/wiki/1016959663602400

如果学习的话,更推荐直接阅读他的教程,讲得更详细。