master
/ 6.2.4 列表的排序.ipynb

6.2.4 列表的排序.ipynb @master

341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
341084b
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
d487d71
 
 
 
 
 
 
 
 
 
 
 
 
 
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  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
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6.6 列表的排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中提供了sort()和reverse()两个方法对列表元素进行排序。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(1)sort()方法  \n",
    "\n",
    "ls.sort(*, key=None, reverse=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ls为要排序的列表,ls.sort()方法可以对列表ls中的数据在原地进行排序,默认规则是直接比较元素大小(注意字符串的比较是逐位比较每个字符的大小)。缺省时参数reverse=False,为升序排序;当设置参数reverse=True时,为降序排序。排序后,列表中的元素变为一个有序序列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[7, 13, 9, 82, 6, 5, 4]\n",
      "[4, 5, 6, 7, 9, 13, 82]\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "L = [7,13,9,82,6,5,4] # 通过赋值创建列表L\n",
    "print(L)            # 输出列表原始元素['73', '13', '9', '82', '6', '5', '04']\n",
    "L.sort()            # 比较字符串大小,缺省升序排序\n",
    "print(L)            # 输出修改过的列表['04', '13', '5', '6', '73', '82', '9'],字符串'13'< '5'\n",
    "print(L.sort())     # L.sort()无返回值,输出None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 95, 88, 77, 56, 46]\n"
     ]
    }
   ],
   "source": [
    "ls = [88,56,95,46,100,77]         # 通过赋值方式创建列表ls\n",
    "ls.sort(reverse=True)             # 比较数字大小,降序排序\n",
    "print(ls)                         # 输出修改过的列表[100, 95, 88, 77, 56, 46]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "参数key可以指定排序时应用的规则,不影响列表中元素的值。例如:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['AM', 'Apple', 'app', 'at']\n",
      "['AM', 'app', 'Apple', 'at']\n",
      "['AM', 'app', 'Apple', 'at']\n",
      "['AM', 'at', 'app', 'Apple']\n",
      "['AM', 'at', 'app', 'Apple']\n"
     ]
    }
   ],
   "source": [
    "L = ['app', 'Apple', 'at', 'AM']\n",
    "L.sort()  # 按字符串大小排序,依序比较各字符Unicode值\n",
    "print(L)  # ['AM', 'Apple', 'app', 'at']   # 默认排序规则排序\n",
    "\n",
    "L.sort(key=str.lower)  # 按转小写后排序\n",
    "print(L)  # ['AM', 'app', 'Apple', 'at']  # 字符串中的字符按小写顺序排序\n",
    "\n",
    "L.sort(key=lambda x: x.lower())  # 按转小写后排序\n",
    "print(L)  # ['AM', 'app', 'Apple', 'at']  # 字符串中的字符按小写顺序排序\n",
    "\n",
    "L.sort(key=len)  # 按字符串长度排序\n",
    "print(L)  # ['AM', 'at', 'app', 'Apple']  # 字符串中的字符按小写顺序排序\n",
    "\n",
    "L.sort(key=lambda x: len(x))  # 按字符串长度排序\n",
    "print(L)  # ['AM', 'at', 'app', 'Apple']  # 字符串中的字符按小写顺序排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用的sort方法,不使用key参数时,Python严格按照列表元素中每个数据字符串的ASCII码大小排序,'A' < ‘a’,故所有'A'开头的字符串都在'a'开头的字符串之前。当提供了参数key = str.lower时,Python执行的操作是将key参数得到的str.lower方法,依次应用于列表中的每个数据项,将字符串中所有字符转换为小写字符,并以此结果作为依据,进行统一排序。排序后,列表中的实际数据项仍为原数据项值,并不会受排序参数key得到的函数和方法影响,key参数得到的函数或方法,只作为排序依据使用。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "内置排序函数sorted(iterable)可以对可迭代对象进行排序,根据 iterable 中的项返回一个新的已排序列表,创新新的排序后的对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sorted(iterable, /, *, key=None, reverse=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "具有两个可选参数,星号*表示它们都必须指定为关键字参数  \n",
    "key 指定带有单个参数的函数,用于从 iterable 的每个元素中提取用于比较的键 (例如 key=str.lower)。 默认值为 None (直接比较元素)。  \r",
    "\r\n",
    "reverse 为一个布尔值。 如果设为 True,则每个列表元素将按反向顺序比较进行排  \n",
    "内置的 sorted() 确保是稳定的,如果一个排序确保不会改变比较结果相等的元素的相对顺序就称其为稳定的  序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['AM', 'Apple', 'app', 'at']\n",
      "['AM', 'app', 'Apple', 'at']\n",
      "['AM', 'app', 'Apple', 'at']\n",
      "['at', 'AM', 'app', 'Apple']\n",
      "['at', 'AM', 'app', 'Apple']\n"
     ]
    }
   ],
   "source": [
    "L = ['app', 'Apple', 'at', 'AM']\n",
    "print(sorted(L))  # ['AM', 'Apple', 'app', 'at']   默认排序规则排序\n",
    "print(sorted(L, key=str.lower))  # ['AM', 'app', 'Apple', 'at']  字符串中的字符按小写顺序排序\n",
    "print(sorted(L, key=lambda x: x.lower()))  # ['AM', 'app', 'Apple', 'at']  字符串中的字符按小写顺序排序\n",
    "print(sorted(L, key=len))  # ['at', 'AM', 'app', 'Apple'] ,  字符串中的字符按长度排序 \n",
    "print(sorted(L, key=lambda x: len(x)))  # ['at', 'AM', 'app', 'Apple']  字符串中的字符按长度排序\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(2)reverse()方法  \n",
    "ls.reverse()方法的作用是不比较元素大小,直接将列表ls中的元素逆序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['73', '13', '9', '82', '6', '5', '04']\n",
      "['04', '5', '6', '82', '9', '13', '73']\n",
      "[77, 100, 46, 95, 56, 88]\n"
     ]
    }
   ],
   "source": [
    "L = ['73','13','9','82','6','5','04']  #通过赋值创建元素为字符串的列表L\n",
    "print(L)           # 输出列表原始元素['73', '13', '9', '82', '6', '5', '04']\n",
    "L.reverse()        # 将列表元素逆序\n",
    "print(L)           # 输出修改过的列表['04', '5', '6', '82', '9', '13', '73']\n",
    "\n",
    "ls = [88,56,95,46,100,77]        # 通过赋值方式创建元素为整数的列表ls\n",
    "ls.reverse()                     # 将列表元素逆序\n",
    "print(ls)                        # 输出修改过的列表[77, 100, 46, 95, 56, 88]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这两种方法都是原地操作,直接修改了原始的列表中的数据,有时,我们只希望在输出时进行排序或逆序输出,不改变列表中的原始数据的顺序。此时,可以使用Python的内置函数sorted()和reversed()。这两个函数都是只返回排序或逆序的对象的结果,而不对原列表进行任何修改,也就是说,不会改变列表中元素原始的顺序。\n",
    "注意:使用这两个内置函数时,列表要放在括号中作为函数的参数。reversed(ls)产生的是一个逆序的对象,需要用list()函数将其转为列表才可以输出。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['73', '13', '9', '82', '6', '5', '04']\n",
      "['04', '13', '5', '6', '73', '82', '9']\n",
      "['73', '13', '9', '82', '6', '5', '04']\n",
      "<list_reverseiterator object at 0x7f12bc126750>\n",
      "[77, 100, 46, 95, 56, 88]\n",
      "[88, 56, 95, 46, 100, 77]\n"
     ]
    }
   ],
   "source": [
    "L = ['73','13','9','82','6','5','04']  # 通过赋值创建列表L\n",
    "print(L)        # 输出列表原始元素    ['73', '13', '9', '82', '6', '5', '04']\n",
    "print(sorted(L))# 将列表元素排序输出  ['04', '13', '5', '6', '73', '82', '9']\n",
    "print(L)        # 列表L元素顺序不变  ['73', '13', '9', '82', '6', '5', '04']\n",
    "\n",
    "ls = [88,56,95,46,100,77]       # 创建列表ls,值为: [88, 56, 95, 46, 100, 77]\n",
    "print(reversed(ls))   # <list_reverseiterator object at 0x00000126AC5CA6E0>\n",
    "\n",
    "print(list(reversed(ls)))     # 将列表元素逆序并转为列表输出 [77, 100, 46, 95, 56, 88]\n",
    "print(ls)             # 列表ls元素顺序不变            [88, 56, 95, 46, 100, 77]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " <font face='楷体' color='red' size=5> 练一练 </font>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实例 5.1 成绩统计分析\n",
    "有10名同学的python课程成绩分别为:94, 89, 96, 88, 92, 86, 69, 95, 78, 85,利用列表分析成绩,输出平均值、最高的3个成绩和最低的3个成绩、成绩中位数。\n",
    "分析:\n",
    "平均成绩可以将所有成绩加和再除以10获得,最高和最低成绩需要排序后输出前后各3个成绩,中位数也需要先排序再求取。如果原列表顺序不需要保留,可以使用列表的sort()方法进行排序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "87.2\n",
      "最高3个成绩为: [96, 95, 94]\n",
      "最低3个成绩为: [69, 78, 85]\n",
      "成绩中位数是:88.50\n",
      "[69, 78, 85, 86, 88, 89, 92, 94, 95, 96]\n"
     ]
    }
   ],
   "source": [
    "# 利用列表存储数据,统计平均成绩、中位数、最高三个成绩和最低三个成绩\n",
    "scores = [94, 89, 96, 88, 92, 86, 69, 95, 78, 85]\n",
    "scores.sort()          # 对成绩列表排序,默认升序,scores 中原来顺序丢失\n",
    "\n",
    "print(sum(scores)/10)  # 利用sum()函数对序列元素求和计算平均成绩\n",
    "print('最高3个成绩为:', scores[-1: -4: -1]) # 后面3个成绩,步长-1表示逆序\n",
    "print('最低3个成绩为:', scores[0: 3])       # 前面3个成绩,顺序输出,升序\n",
    "count = len(scores)# 取得成绩个数\n",
    "\n",
    "if count % 2 == 0: # 当列表元素数目为偶数时,中位数为中间两个数据的算术平均数\n",
    "    median = (scores[count // 2 -1] + scores[count // 2 ])/2\n",
    "else:              # 当列表元素数目为奇数时,中位数即列表中间的数字\n",
    "    median = scores[ count // 2 ]\n",
    "    \n",
    "print('成绩中位数是:{:.2f}'.format(median))\n",
    "print(scores)   \n",
    "# sort()方法使原列表排序发生变化,[69, 78, 85, 86, 88, 89, 92, 94, 95, 96]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "很多时候,希望原列表中的顺序可以被保留下来,这时,可以使用Python内置函数sorted()在输出时进行排序:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "87.2\n",
      "最高3个成绩为: [96, 95, 94]\n",
      "最低3个成绩为: [69, 78, 85]\n",
      "成绩中位数:88.50\n",
      "[94, 89, 96, 88, 92, 86, 69, 95, 78, 85]\n"
     ]
    }
   ],
   "source": [
    "scores = [94, 89, 96, 88, 92, 86, 69, 95, 78, 85]\n",
    "\n",
    "print(sum(scores)/10)\n",
    "print('最高3个成绩为:',sorted(scores)[-1: -4: -1])#输出时排序,不影响原列表\n",
    "print('最低3个成绩为:', sorted(scores)[0: 3])\n",
    "\n",
    "count = len(scores)   # 取得成绩个数\n",
    "if count % 2 == 0: # 当列表元素数目为偶数时,中位数为中间两个数据的算术平均数\n",
    "    median = (sorted(scores)[count // 2 -1] + sorted(scores)[count // 2 ])/2\n",
    "else:              # 当列表元素数目为奇数时,中位数即列表中间的数字\n",
    "    median = sorted(scores)[ count // 2 ]\n",
    "    \n",
    "print('成绩中位数:{:.2f}'.format(median))\n",
    "print(scores)   \n",
    "# sorted()函数不改变原列表顺序[94, 89, 96, 88, 92, 86, 69, 95, 78, 85]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "拓展一下这个问题,当成绩数据保存在文件中时,如何对成绩进行分析?\n",
    "文件中的数据如下:\n",
    "王龙 94\n",
    "张龙 89\n",
    "梁龙 96\n",
    "杨林 88\n",
    "刘雪 92\n",
    "魏琴 86\n",
    "杜鑫 69\n",
    "刘君 95\n",
    "王娜 78\n",
    "周华 85\n",
    "读文件中的数据的应用非常多,可以先将文件中的数据读取为列表形式,再用上述方法对列表中的数据进行分析和统计。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[6.1 score.txt](images/ch6/6.1 score.txt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[94, 89, 96, 88, 92, 86, 69, 95, 78, 85]\n"
     ]
    }
   ],
   "source": [
    "scores = []                   # 创建空列表\n",
    "with open('images/ch6/6.1 score.txt','r',encoding='utf-8') as data:\n",
    "   for line in data:           # 遍历文件对象\n",
    "      line = line.strip()      # 去除行末的换行符\n",
    "      line = line.split()      # 根据空白字符将字符串切分为列表\n",
    "      line = int(line[1])      # 索引方法获取列表中序号为1的元素\n",
    "      scores.append(line)      # 将其转为整数附加到列表末尾\n",
    "print(scores)                  # 输出列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 字符串的处理方法可以连续使用,上述代码可以简化为下面形式\n",
    "scores = []                      # 创建空列表\n",
    "with open('images/ch6/6.1 score.txt','r',encoding='utf-8') as data:\n",
    "   for line in data:             # 遍历文件对象\n",
    "      scores.append(int(line.strip().split()[1]))      \n",
    "print(scores)                    # 输出列表\n",
    "# [94, 89, 96, 88, 92, 86, 69, 95, 78, 85]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实例 5.2 二维列表的排序\n",
    "列表score = [[ 'Angle', '0121701100106',99], [ 'Jack', '0121701100107',86], [ 'Tom', '0121701100109',65], [ 'Smith', '0121701100111', 100], ['Bob', '0121701100115',77], ['Lily', '0121701100117', 59]]\n",
    "每个列表元素的三个数据分别代表姓名、学号和成绩,请分别按姓名、学号和成绩排序输出。\n",
    "分析:二维列表的排序可以用lambda函数指定排序关键字,而且可以指定多个排序关键字,将用于确定排序的关键字按顺序放在同一个括号中,放于lambda关键字的冒号后面即可。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "按姓名排序\n",
      "[['Angle', '0121701100106', 99], ['Bob', '0121701100115', 77], ['Jack', '0121701100107', 86], ['Lily', '0121701100117', 59], ['Smith', '0121701100111', 100], ['Tom', '0121701100109', 77]]\n",
      "按学号排序\n",
      "[['Angle', '0121701100106', 99], ['Jack', '0121701100107', 86], ['Tom', '0121701100109', 77], ['Smith', '0121701100111', 100], ['Bob', '0121701100115', 77], ['Lily', '0121701100117', 59]]\n",
      "优先按成绩排序再按姓名排序\n",
      "[['Lily', '0121701100117', 59], ['Bob', '0121701100115', 77], ['Tom', '0121701100109', 77], ['Jack', '0121701100107', 86], ['Angle', '0121701100106', 99], ['Smith', '0121701100111', 100]]\n"
     ]
    }
   ],
   "source": [
    "# 二维列表元素排序以及根据多个字段用不同的排序规则进行排序\n",
    "score = [[ 'Angle', '0121701100106',99], [ 'Jack', '0121701100107',86], [ 'Tom', '0121701100109',77], [ 'Smith', '0121701100111', 100], ['Bob', '0121701100115',77], ['Lily', '0121701100117', 59]]\n",
    "print('按姓名排序')\n",
    "print(sorted(score, key=lambda x:x[0])) # 按元素中序号为0的元素“姓名”排序\n",
    "print('按学号排序')\n",
    "print(sorted(score, key=lambda x:x[1])) # 按元素中序号为1的元素“学号”排序\n",
    "print('优先按成绩排序再按姓名排序')\n",
    "print(sorted(score, key=lambda x:(x[2],x[0])))  \n",
    "#先按成绩升序排序,成绩相同时再按学号升序排序\n",
    " "
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "按姓名排序\n",
    "[['Angle', '0121701100106', 99], \n",
    "['Bob', '0121701100115', 77], \n",
    "['Jack', '0121701100107', 86], \n",
    "['Lily', '0121701100117', 59], \n",
    "['Smith', '0121701100111', 100], \n",
    "['Tom', '0121701100109', 77]]\n",
    "\n",
    "按学号排序\n",
    "[['Angle', '0121701100106', 99], \n",
    "['Jack', '0121701100107', 86], \n",
    "['Tom', '0121701100109', 77], \n",
    "['Smith', '0121701100111', 100], \n",
    "['Bob', '0121701100115', 77], \n",
    "['Lily', '0121701100117', 59]]\n",
    "\n",
    "优先按成绩排序再按姓名排序\n",
    "[['Lily', '0121701100117', 59], \n",
    "['Bob', '0121701100115', 77], \n",
    "['Tom', '0121701100109', 77], \n",
    "['Jack', '0121701100107', 86], \n",
    "['Angle', '0121701100106', 99], \n",
    "['Smith', '0121701100111', 100]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[6.1 score.txt](images/ch6/6.1 score.txt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 元素为字符串的二维列表排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对列表[('hubei', 'wuhan'), ('hubei', 'huangshi'), ('hubei', 'huanggang'), ('hunan', 'shangsha')]进行排序,先输出默认排序结果;再先按城市名升序排序,城市名相同时按省名升序排序;再先按省名降序排序,省名相同时按城市名升序排序;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于多个排序关键字都是字符串类型的,排序一个升序一个降序时,可以将字符依次转为unicode编码做排序依据,以值的正负表示降序或升序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "city = [('hubei', 'wuhan'), ('hubei', 'huangshi'), ('hubei', 'huanggang'), ('hunan', 'shangsha')]\n",
    "\n",
    "print(sorted(city))\n",
    "print(sorted(city, key=lambda x: (x[1], x[0])))\n",
    "print(sorted(city, key=lambda x: ([-ord(i) for i in x[0]], [ord(i) for i in x[1]])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}