master
/ 7.1.1 集合的创建.ipynb

7.1.1 集合的创建.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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  集合(set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合类型用来保存<font color='red'>**无序**</font>的、<font color='red'>**不重复**</font>的**<font color='red'>不可变数据**</font>,其概念和数学中集合的概念基本一致,如果我们把一定范围的、确定的、可以区别的事物当作一个整体来看待,那么这个整体就是集合,集合中的各个事物称为集合的元素。通常,集合需要满足以下特性:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1.无序性:一个集合中,每个元素的地位都是相同的,元素之间是无序的。\n",
    "2.互异性:一个集合中,任何两个元素都是不相同的,即元素在集合中只能出现一次,集合中不存在重复的元素。\n",
    "3.确定性:给定一个集合和一个任意元素,该元素要么属这个集合,要么不属于这个集合,二者必居其一,不允许有模棱两可的情况出现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kotlin Java C++ Swift Python "
     ]
    }
   ],
   "source": [
    "set1 = {'Python', 'C++', 'Java', 'Kotlin', 'Swift'}  # 集合\n",
    "\n",
    "for elem in set1:         # 遍历集合中的元素\n",
    "    print(elem,end=' ')\n",
    "\n",
    "# 每次运行结果可能不同\n",
    "# C++ Swift Python Kotlin Java\n",
    "# Java Kotlin C++ Swift Python "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "无序性说明集合中的元素并不像列中的元素那样存在某种次序,可以通过索引运算就能访问任意元素,集合并不支持索引运算。  \n",
    "集合的互异性决定了集合中不能有重复元素,这一点也是集合区别于列表的地方,我们无法将重复的元素添加到一个集合中。集合类型必然是支持in和not in成员运算的,这样就可以确定一个元素是否属于集合,也就是上面所说的集合的确定性。  \n",
    "集合的成员运算在性能上要优于列表的成员运算,这是集合的底层存储特性决定的(集合底层使用了哈希存储(散列存储))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可近似将集合看成是<font color='red'>没有值的字典</font>。  \n",
    "常见的用途:  \n",
    "1.成员检测\n",
    "2.从序列中<font color='red'>去除重复项</font>\n",
    "3.数学中的<font color='red'>集合类计算</font>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "目前有两种内置集合类型:  \n",
    "<font color='red'>**集合(set)** </font>  \n",
    "<font color='red'>**不可变集合(frozenset)**</font>  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "set和frozenset的关系类似于列表和元组的关系。  \n",
    "set 类型是可变但 unhashable的,其内容可以使用 add() 和 remove() 这样的方法来改变, 但不能被用作字典的键或其他集合的元素;   \n",
    "frozenset 类型是不可变并且为 hashable,因此它可以被用作字典的键或其他集合的元素。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 集合的创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 非空集合可通过将一系列用逗号分隔的数据放在一对<font color='red'>**大括号**</font>中的方法创建。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5}\n",
      "{'北京', '武汉', '吉林'}\n",
      "{1, 2, 3.14, (1, 2, 3, 3), 'hello'}\n"
     ]
    }
   ],
   "source": [
    "setA = {1, 2, 3, 4, 5}  # 将集合数据赋值给变量,直接创建集合\n",
    "print(setA)             # 输出集合{1, 2, 3, 4, 5}\n",
    "setB = {'吉林', '武汉', '北京'}\n",
    "print(setB)             # {'北京', '吉林', '武汉'}\n",
    "setC = {(1, 2, 3,3), 1, 2, 3.14, 'hello',(1, 2, 3,3)}\n",
    "print(setC)             # {(1, 2, 3), 1, 2, 3.14, 'hello'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/ch7/1.png\" style=\"zoom:60%;\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是,。{}中需要至少有一个元素,不能直接使用<font color='red'>**“{}”**</font>来创建和表示<font color='red'>**空集合**</font>,“{}”将创建一个<font color='red'>**空字典**</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1}\n",
      "<class 'set'>\n"
     ]
    }
   ],
   "source": [
    "setD = {1}    # 将创建一个空字典\n",
    "print(setD)  \n",
    "print(type(setD)) # 输出类型为dict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**集合元素必须为<font color='red'>**不可变类型**</font>,如“{}”内包含可变类型,将会抛TypeError异常。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setC = {[1, 2, 3], 1, 2, 3.14, 'hello'} # 列表[1,2,3]为可变类型抛TypeError异常"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于集合元素<font color='red'>**不重复**</font>如包含重复元素将会<font color='red'>**去重**</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3.14, (1, 2, 3), 'hello'}\n",
      "{0}\n"
     ]
    }
   ],
   "source": [
    "set_1 = {(1, 2, 3), 1, 1, 1, 1, 1, 2, 3.14, 'hello'}  # 包含多个整数1将会去重最终字典中将只包含一个1\n",
    "print(set_1)    # {1, 2, 3.14, 'hello', (1, 2, 3)}\n",
    "set_2 = {0, 0.0 ,0j}    # 由于数值上 0 == 0.0 == 0j所以同样会去重\n",
    "print(set_2)   # {0}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/ch7/2.png\" style=\"zoom:60%;\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 使用 set() 函数可创建集合set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "set() frozenset()函数又称为集合构造器分别用来生成可变和不可变的集合  \n",
    "如果提供一个参数则该<font color='red'>**参数**</font>必须是可迭代的即参数必须是序列列表元组推导式迭代器或字典等支持<font color='red'>**迭代的**</font>对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0, 1, 2, 3, 4, 5, 6, 7}\n",
      "{1, 2, 3, 4, 5}\n",
      "{'p', 's', 'h', 'e', 'o', 'c'}\n"
     ]
    }
   ],
   "source": [
    "setE = set(range(8))            # 通过range创建集合 {0, 1, 2, 3, 4, 5, 6, 7}并赋值给 S5\n",
    "print(setE)                     # 输出{0, 1, 2, 3, 4, 5, 6, 7}\n",
    "\n",
    "setF = set([1, 2, 3, 4, 5])     # set()将列表转为集合 {1, 2, 3, 4, 5}\n",
    "\n",
    "print(setF)                     # 输出{1, 2, 3, 4, 5}\n",
    "\n",
    "print(set('cheeseshop'))        # 字符串转为集合去掉重复元素 {'c', 'p', 'o', 'e', 's', 'h'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 使用 frozenset() 函数可创建不可变集合frozenset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setG = frozenset((1, 3, 5, 7))  # 用frozenset()函数将元组转为不可变集合\n",
    "print(setG)                     # 输出 frozenset({1, 3, 5, 7})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果不提供任何参数默认会生成<font color='red'>**空集合**</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setI = set()             # 使用函数创建一个空集合空集合不能使用{}创建和表示\n",
    "print(setI)              # 输出 set()\n",
    "setJ = frozenset()       # 使用 frozenset()函数构造器创建一个空的不可变集合\n",
    "print(setJ)              # 输出 frozenset()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 利用集合推导式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与列表推导式类似集合也可以通过集合推导式创建  \n",
    "集合推导式与列表推导式的唯一区别在于用<font color='red'>**{}**</font>代替\\[\\]  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0, 1, 4, 9, 16}\n"
     ]
    }
   ],
   "source": [
    "setH = {i*i for i in range(5)}  # 利用推导式生成集合\n",
    "print(setH)                     # {0, 1, 4, 9, 16}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合中的元素必须是hashable类型使用哈希存储的容器都会对元素提出这一要求  \n",
    "所谓hashable类型指的是能够计算出哈希码的数据类型通常不可变类型都是hashable类型  \n",
    "整数int)、浮点小数float)、布尔值bool)、字符串str)、元组tuple  \n",
    "\n",
    "可变类型都不是hashable类型因为可变类型无法计算出确定的哈希码所以它们不能放到集合中例如我们不能将列表作为集合中的元素同理由于集合本身也是可变类型所以集合也不能作为集合中的元素  \n",
    "我们可以创建出嵌套的列表但是我们不能创建出嵌套的集合这一点在使用集合的时候一定要引起注意"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.5 集合变量也可以赋值给另一个变量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但这时两个变量指向相同的内存当一个集合元素发生变化时另一个集合的元素同时也会<font color='red'>**发生变化**</font>  \n",
    "如果需要创建的一个原集合内容一致的<font color='red'>**不同集合对象**</font>可以使用<font color='red'>**s.copy()**</font>的方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'北京', '武汉', '吉林', '深圳'}\n",
      "{'北京', '武汉', '吉林', '深圳'}\n"
     ]
    }
   ],
   "source": [
    "city_set = {'吉林', '武汉', '北京'}\n",
    "new_city_set = city_set  # 将集合变量city_set赋值给new_city_set此时两个变量指向相同的内存\n",
    "city_set.add('深圳')     # 为集合city_set添加一个元素'深圳'new_city_set也会同时变化\n",
    "print(city_set)\n",
    "print(new_city_set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果需要创建的一个原集合内容一致的不同集合对象时可以使用s.copy()的方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'北京', '武汉', '吉林', '深圳'}\n",
      "{'北京', '武汉', '吉林'}\n"
     ]
    }
   ],
   "source": [
    "city_set = {'吉林', '武汉', '北京'}\n",
    "new_city_set = city_set.copy()  # 创建的一个集合变量city_set内容一致的新集合对象new_city_set\n",
    "city_set.add('深圳')            # 为集合city_set添加一个元素'深圳'不影响new_city_set\n",
    "print(city_set)\n",
    "print(new_city_set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 集合去重特性的应用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于集合set内的数据是<font color='red'>**不重复**</font>因此集合构造器常用来对其他的序列数据进行<font color='red'>**去重操作**</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{88, 65, 90, 75}\n",
      "[68, 70, 73, 77]\n"
     ]
    }
   ],
   "source": [
    "setA = set((90, 75, 88, 65, 90))\n",
    "print(setA)                      # 输出{88, 65, 90, 75},重复的90被去掉\n",
    "scores = [80, 85, 88, 93, 88, 81, 96, 73, 85, 77, 77, 86, 89, 68, 93, 82, 95, 81, 80, 70]\n",
    "# 输出不重复的4个最低分 [68, 70, 73, 77]\n",
    "# 用set()函数将score转为集合同时去除重复的数字list()函数再将集合转为列表\n",
    "# 用sorted()函数对集合元素进行升序排序再切片取排序后列表的前4个数\n",
    "print(sorted(set(scores))[0:4])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/ch7/3.png\" style=\"zoom:40%;\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合支持Python内置函数 len(s)用于获取集合s中数据元素的个数  \n",
    "可根据序列对象转换为集合后前后<font color='red'>**长度的变化**</font>判定其中是否存在<font color='red'>**重复元素**</font>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例7.1 奇特的四位数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个四位数各位数字互不相同所有数字之和等于6并且这个数是11的倍数满足这种要求的四位数有多少个各是什么"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**分析**  \n",
    "将这个四位数转为集合如果各位上有相同数字存在重复数字会被去掉则生成的集合长度len(set(str(i)))必小于4只有长度等于4的集合其对应的数中才无重复数字  \n",
    "所有数字之和等于6并不需要从0000遍历到9999只需要遍历到3210即可  \n",
    "若这个数是11的倍数则该数对11取模的值应该等于0  \n",
    "其中map(int,list(str(i)))是将数字i 转为字符再转为列表map(int,ls)函数的作用是将序列ls中的每个元素映射为第一个参数指定的数据类型此处是映射为整型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 输出各位数字互不相同所有数字之和等于6且是11的倍数的4位数\n",
    "ls = []\n",
    "for i in range(1000,3211):  # 各位数加和为6的最大的无重复数字的数是3210\n",
    "    if i % 11 == 0 and sum(map(int,str(i))) == 6 and len(set(str(i))) == 4:\n",
    "        ls.append(i)        # 符合条件的数字加到列表ls里\n",
    "print(len(ls))              # 列表长度就是符合条件的数字的个数 6\n",
    "print(ls)                   # [1023, 1320, 2013, 2310, 3102, 3201]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例7.2 特殊的生日"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "每个日期可以转成8位数字比如2018年5月12日 对应的就是 20180512小明发现自己的生日转成8位数字后8个数字都没有重复而且自他出生之后到今天再也没有这样的日期了请问小明的生日是哪天"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**分析**  \n",
    "可以从当前日期开始向前逐日判定是否为满足条件的日期为提高效率可以略过一些不能表示合法日期的数字例如月份位超过12的和日期位超过31的数字同时确保最后得到的数字是合法日期"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从当前日期向前查找第一个没有重复数字的日期\n",
    "day = 20200202                           # 当前日期整型\n",
    "while True:\n",
    "   day = day - 1                        # 从当前日期向前逐日判定\n",
    "   strDay = str(day)                     # 整型转字符串\n",
    "   if int(strDay[4:6])>13:\n",
    "      continue                    # 忽略月份超过12的数字\n",
    "   elif strDay[4:6] in ['01','03','05','07','08','10','12'] and int(strDay[-2:]) > 31:\n",
    "      continue                    # 以上月份忽略超过31的日期\n",
    "   elif strDay[4:6] in ['04','06','09','11'] and int(strDay[-2:]) > 30:\n",
    "      continue                    # 以上月份忽略超过30的日期\n",
    "   elif strDay[4:6] in ['02'] and int(strDay[-2:]) > 19:\n",
    "      continue                    # 2月份忽略超过19的日期20以后有重复数字\n",
    "   elif len(set(strDay)) == 8:    # 字符串转集合判断无重复数字是否8个\n",
    "      print(strDay)\n",
    "      break                       # 找到第一个满足条件的日期中止循环 19870625"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的代码使用了大量的分支结构用于排除不合法的日期程序较复杂  \n",
    "这个问题也可以借助datetime库里的一些方法实现  \n",
    "获取今天日期的方法是`datetime.now()`,可得到形如2018-09-04的日期  \n",
    "返回日期间隔的方法是`timedelta(days=1)`,括号中的`days=1`表示日期间隔为1天  \n",
    "从当前天向前查看每一天的日期中是否有重复数字第一个出现的没有重复数字的日期就是答案  \n",
    "判断日期中是否有重复数字可用集合方法。\n",
    "\n",
    "使用datetime库简化后的代码如下"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从当前日期向前查找第一个没有重复数字的日期\n",
    "import datetime\n",
    "\n",
    "todays = datetime.datetime.now()          # 获取今天日期形如2020-02-02\n",
    "while True:\n",
    "    todays = todays -datetime.timedelta(days=1)   # 从今天起日期依次减一天\n",
    "    sday = todays.strftime('%Y%m%d')      # 获得格式化的时间形如20190701\n",
    "    if len(set(sday)) == 8:    # 字符串转集合判断无重复数字是否8个\n",
    "        print('出生日期是{}年{}月{}日'.format(sday[:4],sday[4:6],sday[6:]))  \n",
    "        break                             # 找到一个符合条件的日期就结束循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "datetime是一个非常有用的内置库几乎和日期或时间相关的操作都可以找到相关的函数或方法遇到相关的需求可查阅[datetime库官方文档](https://docs.python.org/zh-cn/3/library/datetime.html)获取帮助"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font face='楷体' color='red' size=5> 练一练 </font>\n",
    "\n",
    "##### 猜年龄\n",
    "\n",
    "美国数学家维纳(N.Wiener)智力早熟11岁就上了大学他曾在1935~1936年应邀来中国清华大学讲学一次他参加某个重要会议年轻的脸孔引人注目于是有人询问他的年龄他回答说:“我年龄的立方是个4位数我年龄的4次方是个6位数这10个数字正好包含了从0到9这10个数字每个都恰好出现1次。” 请编程输出当年维纳的年龄。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬\n",
    "\n",
    "本题没有输入‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬,输出应为18维纳当年的年龄)\n",
    "\n",
    "**提示**循环遍历所有可能的年龄将年龄值的立方和4次方的结果转换为字符串并拼接起来若该字符串转化为集合后长度长度仍为10则是正确的年龄"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 请在此处编写代码完成上面的题目的要求\n",
    "\n"
   ]
  },
  {
   "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
}