Repository navigation
Expand file tree
/
Copy pathnative-datatypes.html
More file actions
executable file
·1417 lines (1110 loc) · 87.9 KB
/
Copy pathnative-datatypes.html
File metadata and controls
executable file
·1417 lines (1110 loc) · 87.9 KB
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
<!DOCTYPE html>
<meta charset=utf-8>
<title>고유 자료형 - 파이썬 3로 뛰어들기</title>
<!--[if IE]><script src=j/html5.js></script><![endif]-->
<link rel=stylesheet href=dip3.css>
<style>
body{counter-reset:h1 2}
</style>
<link rel=stylesheet media='only screen and (max-device-width: 480px)' href=mobile.css>
<link rel=stylesheet media=print href=print.css>
<meta name=viewport content='initial-scale=1.0'>
<form action=http://www.google.com/cse><div><input type=hidden name=cx value=014021643941856155761:l5eihuescdw><input type=hidden name=ie value=UTF-8> <input type=search name=q size=25 placeholder="powered by Google™"> <input type=submit name=root value=Search></div></form>
<p>여기 있어요: <a href=index.html>Home</a> <span class=u>‣</span> <a href=table-of-contents.html#native-datatypes>Dive Into Python 3</a> <span class=u>‣</span>
<p id=level>난이도: <span class=u title=beginner>♦♦♢♢♢</span>
<h1>고유 자료형</h1>
<blockquote class=q>
<p><span class=u>❝</span>
모든 철학은 경이로움에서 태어나, 궁금증으로 성장하지만, 무관심으로 생을 마친다.<br>
<span class=u>❞</span><br>— Michel de Montaigne
</blockquote>
<p id=toc>
<h2 id=divingin>뛰어들기</h2>
<p class=f>자료형입니다. <a href=your-first-python-program.html>우리의 첫번째 파이썬 프로그램</a>은 잠시 접어두고, 자료형에 대해서 이야기 해 봅시다. 파이썬의 <a href=your-first-python-program.html#declaringfunctions>모든 값은 그 타입을 갖고 있습니다</a>. 하지만 이를 명시적으로 선언할 필요는 없습니다. 어떻게 그게 가능할까요? 파이썬에서는 각 변수에 할당되는 값의 타입을 보고 변수의 데이터 타입을 유추하기 때문입니다. 그리고 내부적으로 이를 저장해놓기 때문에, 프로그래머가 명시적으로 변수의 타입을 선언해 줄 필요가 없습니다.
<p>파이썬은 다양한 자료형을 가지고 있습니다만, 우선 그 중 중요한 몇 가지만 살펴봅시다:
<ol>
<li><b><font size=2>Boolean</font></b> 은 <code>True</code> 또는 <code>False</code>입니다.
<li><b><font size=2>Numbers</font></b> 는 (<code>1</code>이나 <code>2</code> 같은) 정수일 수도 있고, (<code>1.1</code>이나 <code>1.2</code> 같은) 실수일 수도, (<code>1/2</code>이나 <code>2/3</code> 같은) 분수일 수도 있으며, 심지어 <a href=http://en.wikipedia.org/wiki/Complex_number>복소수</a>일 수도 있습니다.
<li><b><font size=2>String</font></b>은 유니코드 문자의 연속입니다, <i>일례로</i> <abbr>HTML</abbr> 문서는 String입니다.
<li><b><font size=2>Byte</font></b> 와 <b>byte array</b>, <i>일례로</i> <abbr>JPEG</abbr> 이미지 파일을 들 수 있습니다.
<li><b><font size=2>List</font></b> 는 어떤 값들을 순서대로 써놓은 것입니다.
<li><b><font size=2>Tuple</font></b> 은 내용을 변경할수 없는 (immutable) 한 값들을 순서대로 써놓은 것 입니다.
<li><b><font size=2>Set</font></b>은 어떤 값들을 순서에 상관없이 모아둔 것입니다.
<li><b>사전<font size=2>Dictionaries</font></b> 키-값 쌍의 모음들을 순서에 상관없이 모아둔 것입니다.
</ol>
<p>물론 이게 전부는 아닙니다. 파이썬에선 <a href=your-first-python-program.html#everythingisanobject>모든 것이 객체(Object) 입니다</a>. 따라서 모듈(module), 클래스(class), 메소드(method), 파일(file), 심지어 컴파일된 코드(compiled code)도 일종의 데이터 타입입니다. 이 중 몇 가지는 이미 앞에서 다뤘었죠? <a href=your-first-python-program.html#runningscripts>모듈은 __name__ 이라는 특성이 있고</a>, <a href=your-first-python-program.html#docstrings>함수엔 <code>docstrings</code>이라는 특성이 있습니다</a>. 클래스 타입은 <a href=iterators.html>클래스와 반복자</a> 챕터에서 자세히 다루도록 하고요, 파일 타입은 <a href=files.html>파일</a>챕터에서 다루겠습니다.
<p>문자열과 바이트는 매우 중요한데, 복잡하기도 해서 별도 챕터로 뺐습니다. 아무튼 이렇게 별도의 챕터로 빼둔 것들은 그때 다시 배우도록 하고요, 우선은 그를 제외한, 좀 쉬운 것부터 살펴보죠.<p class=a>⁂
<h2 id=booleans>Booleans</h2>
<aside>You can use virtually any expression in a boolean context.</aside>
<p>
Boolean은 참 이나 거짓 가운데 하나를 의미하는 데이터 타입입니다. 파이썬은 이를 위해 <code><dfn>True</dfn></code> 와 <code><dfn>False</dfn></code> 라는 상수를 정의해서 사용하고, 이 상수를 변수에 직접 할당하여 Boolean 타입으로 만들 수 있습니다. 어떤 상황에서는, 주어진 표현식이 반드시 <code><dfn>True</dfn></code> 이거나 <code><dfn>False</dfn></code> 여야 합니다. if 문을 예로 들 수 있습니다. if 문에 사용된 조건식은 반드시 <code><dfn>True</dfn></code> 나 <code><dfn>False</dfn></code> 가운데 하나로 판명나야 합니다. 이런 상황을 Boolean context 라고 부릅니다. Boolean context 에는 어떤 파이썬 표현식도 사용할 수 있습니다. 파이썬이 알아서 <code><dfn>True</dfn></code>나 <code><dfn>False</dfn></code> 중 하나로 평가해 주거든요. 하지만, 자료형마다 서로 다른 룰을 가지고, 참과 거짓이 판명된다는 사실은 알고 계셔야 합니다. 아리송하죠? 역시 예제를 보는 편이 낫겠네요.
<p>
<a href=your-first-python-program.html#divingin><code>humansize.py</code> 에서 가져온 코드를 봅시다</a>:
<pre class='nd pp'><code>if size < 0:
raise ValueError('number must be non-negative')</code></pre>
<p>
<var>size</var>는 정수, 0도 정수 입니다. <code><</code> 는 수 연산자이고요. 그래서, <code>size < 0</code> 라는 파이썬 표현식은 언제나 참 또는 거짓입니다. 파이썬 쉘에서 테스트 해보세요.
<pre class='nd screen'>
<samp class=p>>>> </samp><kbd class=pp>size = 1</kbd>
<samp class=p>>>> </samp><kbd class=pp>size < 0</kbd>
<samp class=pp>False</samp>
<samp class=p>>>> </samp><kbd class=pp>size = 0</kbd>
<samp class=p>>>> </samp><kbd class=pp>size < 0</kbd>
<samp class=pp>False</samp>
<samp class=p>>>> </samp><kbd class=pp>size = -1</kbd>
<samp class=p>>>> </samp><kbd class=pp>size < 0</kbd>
<samp class=pp>True</samp></pre>
<p>
파이썬 버전 2에서와 같이, Boolean 타입을 숫자처럼 쓸 수도 있습니다. <code>True</code>는 <code>1</code>, <code>False</code>는 0을 의미합니다.
<pre class='nd screen'>
<samp class=p>>>> </samp><kbd class=pp>True + True</kbd>
<samp class=pp>2</samp>
<samp class=p>>>> </samp><kbd class=pp>True - False</kbd>
<samp class=pp>1</samp>
<samp class=p>>>> </samp><kbd class=pp>True * False</kbd>
<samp class=pp>0</samp>
<samp class=p>>>> </samp><kbd class=pp>True / False</kbd>
<samp class=traceback>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: int division or modulo by zero</samp></pre>
<p>
아차. 깜빡하고 말씀을 안드렸네요. 0으로 나누면 안됩니다. 알고 계셨죠?.
<p class=a>⁂
<h2 id=numbers>Numbers</h2>
<p>
이번 챕터에서는 다뤄야 할 것들이 굉장히 많습니다. 일단 파이썬 3는 <dfn>정수형(integer)</dfn>과 <dfn>실수형(floating point number)</dfn>을 지원합니다. 앞에서 말씀드렸듯이, 파이썬은 변수 선언시 타입을 별도로 선언하지 않기 때문에, 정수형인지 실수형인지를 판단하려면 값에 <dfn>소숫점</dfn>이 있는지 없는지를 봐야합니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>type(1)</kbd> <span class=u>①</span></a>
<samp class=pp><class 'int'></samp>
<a><samp class=p>>>> </samp><kbd class=pp>isinstance(1, int)</kbd> <span class=u>②</span></a>
<samp class=pp>True</samp>
<a><samp class=p>>>> </samp><kbd class=pp>1 + 1</kbd> <span class=u>③</span></a>
<samp class=pp>2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>1 + 1.0</kbd> <span class=u>④</span></a>
<samp class=pp>2.0</samp>
<samp class=p>>>> </samp><kbd class=pp>type(2.0)</kbd>
<samp class=pp><class 'float'></samp></pre>
<ol>
<li>
어떤 값이나 변수의 타입을 확인하려면 <code>type()</code> 함수를 사용합니다. 당연히 <code>1</code> 은 <code>정수형</code>입니다.
<li>
<code>isinstance()</code> 함수를 사용하면, 첫번째 파라미터로 넘겨진 값이나 변수가 두번째 파라미터로 넘겨진 타입과 같은지 아닌지를 알 수 있습니다.
<li>
<code>정수</code>에 <code>정수</code>를 더하면 <code>정수</code>입니다.
<li>
<code>정수</code>에 <code>실수</code>를 더하면 <code>실수</code>입니다. 파이썬에선 <code>정수</code>와 <code>실수</code>를 더하면, 먼저 정수를 <code>실수</code>로 변경한 후 연산을 적용합니다. 따라서 연산결과는 실수입니다.
</ol>
<h3 id=number-coercion>정수와 실수간 변환하기</h3>
<p>
앞에서 본 것과 같이, 더하기 연산자 같은 연산자 들은 주어진 정수값을 그때 그때 상황에 맞게 먼저 실수값으로 변경후 연산에 적용합니다. 하지만 다음과 같이 명시적으로 타입을 변경할 수도 있습니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>float(2)</kbd> <span class=u>①</span></a>
<samp class=pp>2.0</samp>
<a><samp class=p>>>> </samp><kbd class=pp>int(2.0)</kbd> <span class=u>②</span></a>
<samp class=pp>2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>int(2.5)</kbd> <span class=u>③</span></a>
<samp class=pp>2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>int(-2.5)</kbd> <span class=u>④</span></a>
<samp class=pp>-2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>1.12345678901234567890</kbd> <span class=u>⑤</span></a>
<samp class=pp>1.1234567890123457</samp>
<a><samp class=p>>>> </samp><kbd class=pp>type(1000000000000000)</kbd> <span class=u>⑥</span></a>
<samp class=pp><class 'int'></samp></pre>
<ol>
<li>
<code>float()</code> 함수를 사용해 <code>int</code>형을 <code>float</code>형으로 강제 형 변환할 수 있습니다.
<li>
<code>int()</code> 함수를 사용해 <code>float</code>형을 <code>int</code>형으로 바꿀 수 있습니다.
<li>
<code>int()</code> 함수는 양수의 경우 소수점 아래는 그냥 버립니다.
<li>
<code>int()</code> 함수는 음수의 경우도 소수점 아래는 버립니다.
<li>
실수는 소숫점 아래 15 자리까지만 표현할 수 있습니다.
<li>
정수는 임의의 큰 수를 표현하는데 사용합니다.
</ol>
<blockquote class='note compare python2'>
<p><span class=u>☞</span>
파이썬 2에서는 int 형과 long 형을 따로 정의해 두었습니다. int 형의 크기는 sys.maxint 에 정의되어 있고요. 물론 윈도우인지 리눅스인지, 32비트인지 64비트인지 같은 OS 플랫폼에 따라 달라지긴 하지만, int 형의 크기는 최소한 <code>2<sup>32</sup>-1</code> 입니다. 파이썬 3에서는 long 형을 따로 두지 않고, 모든 정수는 int 형 하나로 표시합니다. 자세한 내용은 <a href=http://www.python.org/dev/peps/pep-0237><abbr>PEP</abbr> 237</a> 를 읽어 보세요.
</blockquote>
<h3 id=common-numerical-operations>파이썬으로 산술 연산 하기</h3>
<p>
숫자를 가지고 할 수 있는 모든 일은 역시 파이썬으로도 할 수 있답니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>11 / 2</kbd> <span class=u>①</span></a>
<samp class=pp>5.5</samp>
<a><samp class=p>>>> </samp><kbd class=pp>11 // 2</kbd> <span class=u>②</span></a>
<samp class=pp>5</samp>
<a><samp class=p>>>> </samp><kbd class=pp>−11 // 2</kbd> <span class=u>③</span></a>
<samp class=pp>−6</samp>
<a><samp class=p>>>> </samp><kbd class=pp>11.0 // 2</kbd> <span class=u>④</span></a>
<samp class=pp>5.0</samp>
<a><samp class=p>>>> </samp><kbd class=pp>11 ** 2</kbd> <span class=u>⑤</span></a>
<samp class=pp>121</samp>
<a><samp class=p>>>> </samp><kbd class=pp>11 % 2</kbd> <span class=u>⑥</span></a>
<samp class=pp>1</samp>
</pre>
<ol>
<li>
<code>/</code> 연산자는 실수 나눗셈을 합니다. 분모와 분자 모두 <code>int</code>형이더라도 결과는 항상 <code>float</code> 형이 됩니다.
<li>
<code>//</code> 연산자는 조금 독특한 정수 나눗셈을 합니다. 만약 결과가 양수라면 소숫점 이하는 무조건 버립니다. 하지만, 조심할게 있습니다.
<li>
만약 <code>//</code> 연산자를 음수에 적용하면, 소숫점 이하는 역시 버리고, 결과를 가장 가까이 있는 자기보다 적은 정수값으로 만듭니다. 결과만 놓고 볼 때는, <code>−5</code> 보다 <code>−6</code>이 더 작으니까, 수학적으로 말하면 반내림과 같습니다. -5 라고 자신있게 말씀하셨던 분 많죠? 앞에서 조심하라고 말씀드렸었죠?
<li>
<code>//</code> 연산자의 결과값이 언제나 정수형인 것은 아닙니다. 분자와 분모 중 하나가 실수형이면, 결과값도 실수입니다. 하지만 실수인 결과값 역시 가장 가까운 작은 정수로 변환됩니다.
<li>
<code>**</code> 연산자는 제곱을 의미합니다. <code>11<sup>2</sup></code>은 <code>121</code>이죠.
<li>
<code>%</code> 연산자는 정수 나눗셈을 하고 난 나머지를 돌려줍니다. <code>11</code>을 <code>2</code>로 나눈 나머지는 <code>1</code>이죠. 그래서 결과는 <code>1</code>입니다.
</ol>
<blockquote class='note compare python2'>
<p>
<span class=u>☞</span>
파이썬2 에서의 <code>/</code> 연산자는 정수 나눗셈을 의미했습니다만, 코드 안에 특별 지시자를 넣어 실수 나눗셈 또한 가능하도록 할 수 있었습니다. 그러나 파이썬3 에서는 <code>/</code> 연산자는 디폴트로 실수 나눗셈을 의미합니다. 더 자세한 내용은 <a href=http://www.python.org/dev/peps/pep-0238/><abbr>PEP</abbr> 238</a>을 참고하세요.
</blockquote>
<h3 id=fractions>분수(Fraction) 다루기</h3>
<p>
파이썬이 정수나 실수 연산만 할 수 있는건 아닙니다. 여러분이 중고등학교 때 배웠던, 수학의 정석에나 나올 법한 복잡한 수학공식들도 파이썬은 척척 해낼 수 있습니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>import fractions</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>x = fractions.Fraction(1, 3)</kbd> <span class=u>②</span></a>
<samp class=p>>>> </samp><kbd class=pp>x</kbd>
<samp class=pp>Fraction(1, 3)</samp>
<a><samp class=p>>>> </samp><kbd class=pp>x * 2</kbd> <span class=u>③</span></a>
<samp class=pp>Fraction(2, 3)</samp>
<a><samp class=p>>>> </samp><kbd class=pp>fractions.Fraction(6, 4)</kbd> <span class=u>④</span></a>
<samp class=pp>Fraction(3, 2)</samp>
<a><samp class=p>>>> </samp><kbd class=pp>fractions.Fraction(0, 0)</kbd> <span class=u>⑤</span></a>
<samp class=traceback>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "fractions.py", line 96, in __new__
raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
ZeroDivisionError: Fraction(0, 0)</samp></pre>
<ol>
<li>
분수를 사용하려면 먼저 <code>fractions</code> 모듈을 임포트해야 합니다.
<li>
분수를 만드려면 <code>Fraction</code> 객체를 만들고, 파라미터로 분자와 분모를 넘겨줍니다.
<li>
파이썬은 어떤 분수 계산도 할 수 있습니다. 결과값으로는 언제나 새로운 <code>Fraction</code> 객체가 반환됩니다. <code>2 * (1/3) = (2/3)</code>입니다.
<li>
<code>Fraction</code> 객체는 분자와 분모를 감지해서 자동으로 크기를 맞춰줍니다. <code>(6/4) = (3/2)</code> 입니다.
<li>
파이썬도 분모가 0이 되면 안된다는 것 쯤은 알고 있습니다.
</ol>
<h3 id=trig>삼각함수(Trigonometry) 다루기</h3>
<p>
You can also do basic trigonometry in Python.
기본적인 삼각함수도 사용할 수 있습니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>import math</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>math.pi</kbd> <span class=u>①</span></a>
<samp class=pp>3.1415926535897931</samp>
<a><samp class=p>>>> </samp><kbd class=pp>math.sin(math.pi / 2)</kbd> <span class=u>②</span></a>
<samp class=pp>1.0</samp>
<a><samp class=p>>>> </samp><kbd class=pp>math.tan(math.pi / 4)</kbd> <span class=u>③</span></a>
<samp class=pp>0.99999999999999989</samp></pre>
<ol>
<li>
<code>math</code> 모듈은 원주율을 의미하는 &pi 상수를 정의하고 있습니다.
<li>
math 모듈은 <code>sin()</code>, <code>cos()</code>, <code>tan()</code> 같은 기본 삼각함수들 뿐만 아니라, <code>asin()</code>같이 고급 삼각 함수도 지원합니다.
<li>
<code>tan(π / 4)</code>는 <code>1.0</code>을 반환합니다. <code>0.99999999999999989</code>가 아닙니다. 파이썬이 무한정밀도(infinite precision)을 지원하는 것은 아니거든요.
</ol>
<h3 id=numbers-in-a-boolean-context>숫자도 참 또는 거짓이 될 수 있습니다</h3>
<aside>
0은 false 이고, 0이 아닌 숫자는 true입니다.
</aside>
<p>
<code>if</code> 절 같은 곳에서는 <a href=#booleans>숫자를 참/거짓을 판별할 때 사용</a>할 수 있습니다. 0은 false로 0이 아닌 숫자는 true 로 판별됩니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>def is_it_true(anything):</kbd> <span class=u>①</span></a>
<samp class=p>... </samp><kbd class=pp> if anything:</kbd>
<samp class=p>... </samp><kbd class=pp> print("yes, it's true")</kbd>
<samp class=p>... </samp><kbd class=pp> else:</kbd>
<samp class=p>... </samp><kbd class=pp> print("no, it's false")</kbd>
<samp class=p>...</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(1)</kbd> <span class=u>②</span></a>
<samp>yes, it's true</samp>
<samp class=p>>>> </samp><kbd class=pp>is_it_true(-1)</kbd>
<samp>yes, it's true</samp>
<samp class=p>>>> </samp><kbd class=pp>is_it_true(0)</kbd>
<samp>no, it's false</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(0.1)</kbd> <span class=u>③</span></a>
<samp>yes, it's true</samp>
<samp class=p>>>> </samp><kbd class=pp>is_it_true(0.0)</kbd>
<samp>no, it's false</samp>
<samp class=p>>>> </samp><kbd class=pp>import fractions</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(fractions.Fraction(1, 2))</kbd> <span class=u>④</span></a>
<samp>yes, it's true</samp>
<samp class=p>>>> </samp><kbd class=pp>is_it_true(fractions.Fraction(0, 1))</kbd>
<samp>no, it's false</samp></pre>
<ol>
<li>
파이썬 쉘 안에서도 함수를 정의할 수 있답니다. 함수를 작성해 나갈때는 엔터키를 이용해 다음 행으로 계속할 수 있고, 함수 정의가 끝났을때는 엔터키를 두번 사용해 공백 라인이 맨 마지막에 오도록 하면 됩니다.
<li>
boolean 값이 와야 하는 자리에 숫자가 사용되면 true 나 false 로 판명됩니다.
<li>
실수값도 마찬가지로 0이 아니면 <code>True</code> 입니다. <code>0.0</code>만 <code>False</code> 입니다. 반올림 등의 연산을 실수에 적용할 때는 조심하세요. <code>0.0000000000001</code> 같은 값도 0이 아니기 때문에 <code>True</code>로 판명됩니다.
<li>
분수도 역시 0이 아니면 <code>True</code> 입니다. <code>Fraction(0, n)</code>의 경우 n에 어떤 값을 넣더라도 <code>False</code> 입니다. 이를 제외한 나머지는 모두 <code>True</code>입니다
</ol>
<p class=a>⁂
<h2 id=lists>리스트 (List)</h2>
<p>
리스트 (List) 데이터 타입은 파이썬에서 없어서는 안 될 충실한 심복중 하나입니다. list라는 단어를 듣는 순간, 이렇게 생각하실지도 모르겠습니다. "음, 먼저 사이즈를 정해서 미리 선언해주고, 같은 데이터 타입만 집어 넣을 수 있겠군". 파이썬의 list 데이터 타입을 다른 프로그래밍 언어의 배열과 비슷할 거라고 생각하셨다면, 틀렸습니다. 파이썬 list는 그것보다 훨씬 멋지거든요.
<blockquote class='note compare perl5'>
<p>
<span class=u>☞</span>
펄과 비교하면, list는 펄 5의 배열과 유사합니다. 한편, 펄에서는 배열의 변수명이 항상 <code>@</code>로 시작해야 하지만, 파이썬엔 그런 제약이 없습니다. 파이썬은 내부적으로 데이터 형을 관리하기 때문에 명시적으로 나타낼 필요가 없는거죠.
</blockquote>
<blockquote class='note compare java'>
<p>
파이썬 list는 다른 언어, 가령, 자바의 배열보다 훨씬 강력합니다. 물론 딱 배열처럼만 사용하려면 그렇게 사용할 수도 있습니다. 하지만, 어떤 타입의 객체도 담을 수 있고, 그 크기가 동적으로 늘어날 수 있다는 점에서는 자바의 <code>ArrayList</code> 클래스에 비유할 수 있겠네요.
</blockquote>
<h3 id=creatinglists>list 생성하기</h3>
<p>
파이썬 list를 만드는 방법은 간단합니다. 꺽쇠 안에 값을 적어주고, 콤마로 구분하면 됩니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'mpilgrim', 'z', 'example']</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'b', 'mpilgrim', 'z', 'example']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[0]</kbd> <span class=u>②</span></a>
<samp class=pp>'a'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[4]</kbd> <span class=u>③</span></a>
<samp class=pp>'example'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[-1]</kbd> <span class=u>④</span></a>
<samp class=pp>'example'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[-3]</kbd> <span class=u>⑤</span></a>
<samp class=pp>'mpilgrim'</samp></pre>
<ol>
<li>
다섯개의 원소를 가진 list를 정의했습니다. 출력 결과에 주목하세요. 순서가 변하지 않고 그대로입니다.
<li>
list는 배열처럼 사용할 수 있다고 앞에서 말씀드렸죠? <code>a_list[0]</code> 은 alist 라는 list의 첫번째 원소를 가져옵니다.
<li>
맨 마지막 아이템인 5번째 아이템은 <code>a_list[4]</code> 로 가져옵니다.
<li>
인덱스에 음수값을 주면 뒤에서부터 카운트 해온 값을 반환합니다. <code>a_list[-1]</code> 는 뒤에서 첫번째 아이템, 그러니까 맨 마지막 아이템을 반환합니다.
<li>
혹시 음수값을 사용한 예가 잘 이해가 안되시는 분들은 이런 식으로 한번 생각해보세요. <code>a_list[-<var>n</var>] == a_list[len(a_list) - <var>n</var>]</code>. 그러니까 이 예제에서는 이렇게 됩니다. <code>a_list[-3] == a_list[5 - 3] == a_list[2]</code>.
</ol>
<h3 id=slicinglists>list 쪼개기 (Slicing List)</h3>
<aside>
a_list[0]는 a_list의 첫번째 아이템입니다.
</aside>
<p>
정의된 list에 대해 그 일부분을 떼내어 새로운 list로 정의할 수 있습니다. 이를 리스트 쪼개기 (list slicing)라고 합니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'b', 'mpilgrim', 'z', 'example']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[1:3]</kbd> <span class=u>①</span></a>
<samp class=pp>['b', 'mpilgrim']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[1:-1]</kbd> <span class=u>②</span></a>
<samp class=pp>['b', 'mpilgrim', 'z']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[0:3]</kbd> <span class=u>③</span></a>
<samp class=pp>['a', 'b', 'mpilgrim']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[:3]</kbd> <span class=u>④</span></a>
<samp class=pp>['a', 'b', 'mpilgrim']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[3:]</kbd> <span class=u>⑤</span></a>
<samp class=pp>['z', 'example']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[:]</kbd> <span class=u>⑥</span></a>
<samp class=pp>['a', 'b', 'mpilgrim', 'z', 'example']</samp></pre>
<ol>
<li>
list를 쪼갤 때는 인덱스 두개와 그 사이에 콜론을 적어줍니다. 결과로 첫번째 인덱스 아이템(예에서는 <code>a_list[1]</code>) 을 포함하고, 두번째 인덱스의 바로 앞 아이템까지(예에서는 <code>a_list[3]</code>)를 포함하는 list를 반환합니다.
<li>
list를 쪼갤때 인덱스로 음수값을 줘도 됩니다. 헷갈리시면 이런 식으로 생각하셔도 됩니다. 첫 번째 인덱스는 포함시키고 싶은 파트의 첫 번째 위치입니다. 두 번째 인덱스는 포함시키고 싶지 않은 파트의 첫 번째 위치이고요. 그리고 이 둘 사이의 아이템을 취한 것이 결과입니다.
<li>
list의 인덱스는 0부터 시작합니다. 따라서 <code>a_list[0:3]</code>은 a_list 라는 list의 맨 처음부터 3개의 아이템입니다. <code>a_list[0]</code> 부터 시작하여 <code>a_list[3]</code>의 바로 앞까지 입니다.
<li>
시작 인덱스가 0인 경우엔 생략이 가능합니다. 따라서 <code>a_list[:3]</code> 는 <code>a_list[0:3]</code>와 같은 의미입니다.
<li>
마찬가지 원리로 종료 인덱스가 list의 길이와 같은 경우엔 생략이 가능합니다. 따라서 <code>a_list[3:]</code> 는 <code>a_list[3:5]</code> 와 같은 의미입니다. <code>a_list</code>에는 다섯 개의 아이템이 있기 때문입니다. list 쪼개기에서 아름다운 대칭의 미가 느껴지지 않나요? <code>a_list[:3]</code> 는 list의 앞부분 3개 아이템을 반환하고, <code>a_list[3:]</code>는 이를 제외한 뒷부분 전부의 아이템을 반환합니다. 따라서 이렇게 일반화할 수 있겠네요. <code>a_list[:<var>n</var>]</code> 는 언제나 앞쪽 n개의 아이템을 반환하고, <code>a_list[<var>n</var>:]</code>는 n번째 아이템부터 list 끝까지를 반환합니다
<li>
만약 시작과 종료 인덱스 모두를 생략하면, list 내 모든 아이템을 포함한다는 의미입니다. 원래 list랑 똑같은 복사본이 생기는 것입니다. 이를 이용하여, <code>a_list[:]</code> 라고 써주면 간단히 <code>a_list</code> list를 복사할 수 있습니다.
</ol>
<h3 id=extendinglists>list에 아이템 추가하기</h3>
<p>
list에 아이템을 추가하는 방법들을 알아봅니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a']</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_list = a_list + [2.0, 3]</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>a_list</kbd> <span class=u>②</span></a>
<samp class=pp>['a', 2.0, 3]</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.append(True)</kbd> <span class=u>③</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 2.0, 3, True]</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.extend(['four', 'Ω'])</kbd> <span class=u>④</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 2.0, 3, True, 'four', 'Ω']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.insert(0, 'Ω')</kbd> <span class=u>⑤</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['Ω', 'a', 2.0, 3, True, 'four', 'Ω']</samp></pre>
<ol>
<li>
<code>+</code> 연산자를 이용하여 list를 합칠 수 있고, 결과로는 새로운 list가 반환됩니다. list에 담을 수 있는 아이템 갯수에는 제한이 없는데, 정확히 말하면 사용할 수 있는 메모리에 제한이 없다면 제약이 없는 셈입니다. 만약 구현하려는 어플리케이션의 사용 가능한 메모리가 많지 않다면, 사용시 주의해야 합니다. 이 코드가 하는 일을 두 단계로 나누면, 먼저 <var>a_list</var> 에 <var>[2.0, 3]</var>을 합치고, 그 결과를 다시 <var>a_list</var> 에 할당합니다. 다루고 있는 list의 크기가 크지 않다면 괜찮겠지만, 상당한 크기인 경우에는 두번째 단계인 할당이 일어나는 순간 많은 양의 메모리가 요구될 수 있습니다. 그 점을 미리 염두에 두셔야 합니다.
<li>
list 내부에는 어떤 타입의 데이터도 함께 담을 수 있습니다. 꼭 같은 타입의 데이터일 필요는 없습니다. 이 예제는 string, 실수, 정수 이렇게 서로 다른 데이터 타입을 가진 list를 보여줍니다.
<li>
<code>append()</code> 메소드를 이용해 list의 맨 끝에 아이템을 추가할 수 있습니다. 이제 4개의 서로 다른 데이터 타입이 list 안에서 공존하는군요.
<li>
list는 파이썬 내부에선 클래스로 구현되있습니다. 따라서 list를 하나 만든다는 것은 list 클래스의 인스턴스를 하나 만든다는 것과 동일합니다. 모든 인스턴스에는 메소드가 있고, list 또한 예외가 아닙니다. 이 예제 코드에서는 list 클래스의 <code>extend()</code> 메소드를 이용하여 기존 list에 아이템을 추가하고 있습니다. 메소드 인자가 추가할 데이터입니다.
<li>
<code>insert()</code> 메소드는 아이템 하나를 정해진 위치에 삽입할 때 사용합니다. 첫번째 인자는 삽입하고 싶은 위치이고, 동작이 성공적이면 뒤쪽에 위치한 아이템들은 자리가 하나씩 뒤로 밀리게 됩니다. 삽입하는 데이터가 기존 list에 이미 존재하더라고 상관없습니다. list는 중복된 데이터도 허용하기 때문입니다. 예제 코드에서는 <code>'Ω'</code> 라는 값이 첫번째 인덱스와 마지막 인덱스, 이렇게 두 군데에서 보이고 있습니다.
</ol>
<blockquote class='note compare perl'>
<p>
<span class=u>☞</span><code><var>a_list</var>.insert(0, <var>value</var>)</code>는 펄 함수 중 <code>unshift()</code> 함수와 비슷합니다. list의 맨 앞에 아이템을 삽입하고 나머지 아이템들은 전부 뒤로 한 칸씩 이동시킵니다.
</blockquote>
<p>
이번에는 <code>append()</code>와 <code>extend()</code>의 차이점에 대해 알아 봅시다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'c']</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.extend(['d', 'e', 'f'])</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'b', 'c', 'd', 'e', 'f']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>len(a_list)</kbd> <span class=u>②</span></a>
<samp class=pp>6</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list[-1]</kbd>
<samp class=pp>'f'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.append(['g', 'h', 'i'])</kbd> <span class=u>③</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'b', 'c', 'd', 'e', 'f', ['g', 'h', 'i']]</samp>
<a><samp class=p>>>> </samp><kbd class=pp>len(a_list)</kbd> <span class=u>④</span></a>
<samp class=pp>7</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list[-1]</kbd>
<samp class=pp>['g', 'h', 'i']</samp></pre>
<ol>
<li>
<code>extend()</code> 메소드는 list 타입의 인자를 받아서, 그 내부의 아이템들을 <var>a_list</var>안에 추가함으로써, 기존의 list를 그만큼 연장해(extend)줍니다.
<li>
처음 3개의 아이템을 가진 list에 3개의 아이템이 있는 또 다른 list를 이용해 늘렸으므로, 이제 아이템의 갯수는 6개가 되었습니다.
<li>
한편 <code>append()</code> 메소드는 인자로 들어온 값을 list에 추가합니다. 인자는 하나이며, 인자의 타입은 어떤 타입이라도 괜찮습니다. 예제코드에서는 3 개의 아이템이 있는 list를 인자로 넘겨주고 있습니다.
<li>
앞에서 list 내 아이템의 갯수가 6개 였으니까, 이제 9개가 되어야겠군요. 앗. 그런데, 파이썬 쉘은 7개라고 나오네요. 왜죠? 이게 바로 extend 메소드와 append 메소드 간의 차이점입니다. extend 메소드는 인자로 넘어온 list내 아이템 하나 하나를 추가해주지만, append 메소드는 인자가 list건 뭐건 상관없이 하나의 객체로 판단하고 이를 기존 list 끝에 추가합니다. 그래서 예제코드에선 ['g', 'h', 'i'] 가 3개의 개별적인 아이템이 아닌, 전체 list 하나가 통째로 list 안에 들어가게 된거죠. list 객체는 다른 list 객체도 내부 아이템으로 가질 수 있다는 사실을 잊지마세요.
</ol>
<h3 id=searchinglists>
리스트 검색하기
</h3>
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'new', 'mpilgrim', 'new']</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.count('new')</kbd> <span class=u>①</span></a>
<samp class=pp>2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>'new' in a_list</kbd> <span class=u>②</span></a>
<samp class=pp>True</samp>
<samp class=p>>>> </samp><kbd class=pp>'c' in a_list</kbd>
<samp class=pp>False</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.index('mpilgrim')</kbd> <span class=u>③</span></a>
<samp class=pp>3</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.index('new')</kbd> <span class=u>④</span></a>
<samp class=pp>2</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.index('c')</kbd> <span class=u>⑤</span></a>
<samp class=traceback>Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list</samp></pre>
<ol>
<li>
특정 값이 list 내에 몇 개나 있는지 그 횟수를 알고 싶을때는 <code>count()</code> 메소드를 사용하세요.
<li>
그냥 어떤 값이 들어 있는지 아닌지만 알고 싶다면 <code>in</code> 연산자를 이용하는 편이 간단하고, 성능도 좀 더 빠릅니다. 결과로 <code>True</code> 나 <code>False</code>가 반환됩니다.
<li>
특정 값이 list내에서 몇 번째 있는지 알고 싶다면 <code>index()</code> 메소드를 사용하세요. 이 함수는 list 전체를 검색하여 해당 위치(0 부터 시작합니다) 를 반환합니다. 검색을 수행할 위치도 지정할 수 있는데요, 두번째 파라미터가 검색을 시작할 위치를 의미하고, 세번째 파라미터가 검색을 끝낼 위치를 의미합니다.
<li>
찾고자 하는 값이 list 내에 여러 번 등장하더라도, <code>index()</code> 메소드는 처음으로 발견한 위치를 반환합니다. 예에서 <code>'new'</code> 라는 문자열은 <code>a_list[2]</code> 에 하나, <code>a_list[4]</code>에 다른 하나, 이렇게 모두 두 번 등장합니다. 하지만, <code>index()</code> 메소드는 첫번째 위치인 2만 반환합니다.
<li>
검색대상이 발견되지 않으면, 예외를 일으킵니다.
</ol>
<p>
잠깐만요. 뭔가 맘에 안듭니다. 보통 다른 언어같은 경우엔 검색하는 값이 없으면 <code>-1</code> 같은 값을 리턴해서 에러를 나타내잖아요? 파이썬도 그렇게 하면 안되나요? 예외까지 발생 시키는건 좀 오바 같은데요. 이렇게 생각하시는 분도 분명 계실겁니다. 하지만 한번 더 생각해보세요. 우리 프로그래머들은 대부분 게으릅니다. 만약 <code>-1</code>을 리턴받았는데, 에러값 조사도 꼼꼼히 하지 않고 그 위치에 있는 데이터를 읽으려고 하면 어떤 일이 생길까요? 아마 프로그램이 꽥 소리를 내며 죽을 수도 있습니다. 이런 코드는 잘 돌다가 꼭 금요일 밤에 비명횡사하기도 합니다. 금요일 밤 11시에 이런 코드를 디버깅하며 밤을 지새우기 보다, 차라리 언어레벨에서 예외를 던져주는 편이 훨씬 낫습니다. 물론, 예외 처리도 잘 해주지 않았다면 프로그램이 죽는건 마찬가지겠지만, 디버깅은 훨씬 더 쉬울겁니다. 예외를 맨 처음 던진 곳을 찾아가면 되니까요. 파이썬의 이런 디자인, 정말 멋지지 않나요?
<h3 id=removingfromlists>리스트에서 아이템 삭제하기</h3>
<aside>list는 빈 공간을 허용하지 않습니다.</aside>
<p>list는 배열과 달리 아이템을 추가하면 그 크기가 동적으로 늘어나고, 삭제하면 동적으로 줄어듭니다.
앞에서는 list에 아이템을 추가해 list가 동적으로 확장시키는 방법을 알아봤으니, 이제부턴 list내 아이템을 삭제하는 방법을 알아봅시다. 아이템을 추가할 때와 마찬가지로 몇 가지 다른 방법을 사용할 수 있습니다.
Lists can expand and contract automatically. You’ve seen the expansion part. There are several different ways to remove items from a list as well.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'new', 'mpilgrim', 'new']</kbd>
<samp class=p>>>> </samp><kbd class=pp>a_list[1]</kbd>
<samp class=pp>'b'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>del a_list[1]</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'new', 'mpilgrim', 'new']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list[1]</kbd> <span class=u>②</span></a>
<samp class=pp>'new'</samp></pre>
<ol>
<li>
del 구문을 이용하여 list 내 특정 아이템을 삭제할 수 있습니다.
<li>
list에서 특정 위치의 아이템을 삭제했다고 해서, 그 자리가 마치 이빨빠진 자리처럼 계속 비워져 있지는 않습니다. 그 뒷부분에 위치한 아이템들이 자동으로, 차례대로 이동하여 빈자리를 메꿔줍니다. 따라서 여전히 그 자리는 다른 아이템에 의해 채워지게 됩니다.
</ol>
<p>
어떤 아이템을 지우고 싶은데 위치를 모른다고요? 문제 없습니다. 위치 인덱스 대신 삭제하고 싶은 값을 직접 입력하면 됩니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.remove('new')</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'mpilgrim', 'new']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.remove('new')</kbd> <span class=u>②</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'mpilgrim']</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list.remove('new')</kbd>
<samp class=traceback>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list</samp></pre>
<ol>
<li>
<code>remove()</code> 메소드도 삭제에 사용하는 메소드 입니다. 삭제하고 싶은 아이템의 값을 파라미터로 받아 list내에서 첫번째로 발견되는 해당 아이템을 삭제합니다. 다시 한번 말씀드리지만, 특정 아이템이 삭제된 자리는 그 뒤의 아이템들이 자동으로 차례차례 메꿔줍니다.
<li>
list 내 존재하지 않는 값을 삭제하려고 하면 예외가 발생됩니다.
</ol>
<h3 id=popgoestheweasel>리스트에서 아이템 삭제하기: 보너스</h3>
<p>
Another interesting list method is <code>pop()</code>. The <code>pop()</code> method is yet another way to <a href=#removingfromlists>remove items from a list</a>, but with a twist.
<code>pop()</code>이라는 메소드를 이용하여 <a href=#removingfromlists>list에서 아이템을 제거</a>할 수도 있습니다. 하지만, 주의할 점이 있습니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'new', 'mpilgrim']</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.pop()</kbd> <span class=u>①</span></a>
<samp class=pp>'mpilgrim'</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'b', 'new']</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.pop(1)</kbd> <span class=u>②</span></a>
<samp class=pp>'b'</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list</kbd>
<samp class=pp>['a', 'new']</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list.pop()</kbd>
<samp class=pp>'new'</samp>
<samp class=p>>>> </samp><kbd class=pp>a_list.pop()</kbd>
<samp class=pp>'a'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list.pop()</kbd> <span class=u>③</span></a>
<samp class=traceback>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop from empty list</samp></pre>
<ol>
<li>
<code>pop()</code> 메소드를 인자없이 호출하면 list의 맨 마지막 아이템을 반환하고, 해당 아이템은 삭제됩니다.
<li>
<code>pop()</code> 메소드에 인자로 위치 인덱스를 주면, 해당 아이템을 반환후 삭제합니다.
<li>
비어있는 list에 호출하면 예외가 발생됩니다.
</ol>
<blockquote class='note compare perl'>
<p>
인자없는 <code>pop()</code> 메소드 호출은 펄의 <code>pop()</code> 함수와 유사합니다. list 맨 마지막 원소를 반환하고, list 내에서는 삭제합니다. 펄과 다른 점은, list의 맨 앞부분 원소를 삭제할 때, 펄은 <code>shift()</code>라는 메소드를 따로 두고 있지만, 파이썬은 인자로 <code>0</code>을 주면 된다는 점입니다.
</blockquote>
<h3 id=lists-in-a-boolean-context>list로 참, 거짓 판단하기</h3>
<aside>
list내에 아이템이 하나라도 들어있다면, 이 list는 True 로 사용될 수 있습니다.
</aside>
<p>
<code>if</code>문과 같이 <a href=#booleans>참, 거짓을 판별하는 구문</a>에서도 list를 사용할 수 있습니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>def is_it_true(anything):</kbd>
<samp class=p>... </samp><kbd class=pp> if anything:</kbd>
<samp class=p>... </samp><kbd class=pp> print("yes, it's true")</kbd>
<samp class=p>... </samp><kbd class=pp> else:</kbd>
<samp class=p>... </samp><kbd class=pp> print("no, it's false")</kbd>
<samp class=p>...</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true([])</kbd> <span class=u>①</span></a>
<samp>no, it's false</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(['a'])</kbd> <span class=u>②</span></a>
<samp>yes, it's true</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true([False])</kbd> <span class=u>③</span></a>
<samp>yes, it's true</samp></pre>
<ol>
<li>
빈 list는 false를 의미합니다.
<li>
list내에 아이템이 하나라도 들어있으면 true로 판명됩니다.
<li>
list내에있는 아이템의 값과는 관계없이, 비어있는 list가 아니라면 true로 판명됩니다.
</ol>
<p class=a>⁂
<h2 id=tuples>튜플 (Tuple)</h2>
<p><dfn>튜플</dfn>은 list의 일종입니다. 일반 list와 다른점은 내부 아이템의 수정이 불가능합니다. 튜플은 일단 생성되고 나면 어떤 방식으로든 수정이 불가능 합니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple = ("a", "b", "mpilgrim", "z", "example")</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_tuple</kbd>
<samp class=pp>('a', 'b', 'mpilgrim', 'z', 'example')</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple[0]</kbd> <span class=u>②</span></a>
<samp class=pp>'a'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple[-1]</kbd> <span class=u>③</span></a>
<samp class=pp>'example'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple[1:3]</kbd> <span class=u>④</span></a>
<samp class=pp>('b', 'mpilgrim')</samp></pre>
<ol>
<li>
튜플을 정의하는 방법은 list와 동일합니다. 다만 list에서는 둥근괄호를 사용하였지만, 튜플에서는 각진 괄호를 사용합니다.
<li>
튜플도 list와 마찬가지로 첫번째 원소는 0부터 시작합니다.
<li>
list와 마찬가지로 인덱스에 마이너스 값이 사용되면 뒤쪽 위치에서부터 카운트합니다.
<li>
list와 마찬가지로 쪼개기(slicing)도 가능합니다. list에서도 쪼개기를 하면, 새로운 list가 만들어지는 것처럼 튜플에서도 쪼개기를 하면 그 결과로 새로운 튜플이 생성됩니다.
</ol>
<p>
튜플이 list와 다른점 중 눈여겨 볼 점은 일단 만들어지고 난 다음엔 수정이 불가능하다는 것입니다. 튜플이란 결국 읽기 전용 list인 셈이고, 이런 특징을 고상하게 말하면 <dfn>immutable</dfn> 하다고 합니다. 튜플은 읽기 전용 list이므로 뭔가 변경을 할때 사용할 만한 메소드를 하나도 지원하지 않습니다. <code>append()</code>, <code>extend()</code>, <code>insert()</code>, <code>remove()</code>, and <code>pop()</code> 와 같은 메소드들이 하나도 없습니다. 다만 쪼개기 (slicing) 정도는 지원하기 때문에, 어떤 값이 들어있는지 검사할 때 사용할 수 있겠습니다.
<pre class=screen>
# 앞 예제에서 계속 이어집니다
<samp class=p>>>> </samp><kbd class=pp>a_tuple</kbd>
<samp class=pp>('a', 'b', 'mpilgrim', 'z', 'example')</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple.append("new")</kbd> <span class=u>①</span></a>
<samp class=traceback>Traceback (innermost last):
File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'append'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple.remove("z")</kbd> <span class=u>②</span></a>
<samp class=traceback>Traceback (innermost last):
File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'remove'</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_tuple.index("example")</kbd> <span class=u>③</span></a>
<samp class=pp>4</samp>
<a><samp class=p>>>> </samp><kbd class=pp>"z" in a_tuple</kbd> <span class=u>④</span></a>
<samp class=pp>True</samp></pre>
<ol>
<li>
이미 만들어진 튜플에 새로운 아이템을 추가할 수는 없습니다. <code>append()</code> 나 <code>extend()</code> 같은 메소드는 없다구요.
<li>
이미 만들어진 튜플로부터 어떤 값을 삭제할 수는 없습니다. <code>remove()</code> or <code>pop()</code> 같은 메소드는 없거든요.
<li>
튜플안에 들어있는 어떤 값을 검색하는 것은 문제가 없습니다. 검색은 수정이 아니잖아요.
<li>
튜플내의 어떤 값을 검색할 때 <code>in</code> 연산자를 사용해도 됩니다.
</ol>
<p>
그래서, 튜플로 뭘 할 수 있을까요?
</p>
<ul>
<li>
튜플은 list보다 빠릅니다. 여러분이 만약 상수값을 가진 list가 필요하고, 추후 변경없이 검색에만 사용할거라고 판단되면 list를 만드는 대신 튜플을 만드세요.
<li>
튜플은 읽기전용 list이므로, 변경을 가하려고 하는 순간 에러를 발생시킵니다. 사용자 코드로부터 여러분의 데이터를 안전하게 지키고 싶다면 list 대신 튜플을 사용하세요. 마치 <code>assert</code>를 이용하여 데이터를 방어하는 것과 같은 효과를 볼 수 있습니다.
<li>
튜플은 변경 불가능하므로(<i>immutable</i>), 딕셔너리의 키 값으로 사용할 수 있습니다. 특히 튜플 내의 아이템이 만약 string과 같이 <i>immutable</i>한 데이터 타입의 경우엔 더더욱 그렇습니다. 하지만, list는 immutable 하지 않으므로 딕셔너리의 키 값으로 사용될 수 없습니다.
</ul>
<blockquote class=note>
<p>
<span class=u>☞</span>튜플을 list로 전환하거나, 꺼꾸로 list를 튜플로 전환하는 것도 가능합니다. 이를 위해 파이썬의 내장함수인 <code>tuple()</code> 은 list를 튜플로 변경할 때 사용할 수 있습니다. 그리고 <code>list()</code> 는 튜플을 list로 변경할 때 사용합니다. list나 튜플 내부에 들어있던 아이템에는 전혀 영향을 미치지 않습니다. 다만 list에서 튜플로, 또는 튜플에서 list로 타입을 변경할 뿐입니다. 우리가 어렸을 적 놀던 얼음 땡을 기억하시나요? 이 함수들이 바로 파이썬의 얼음 땡 함수입니다. <code>tuple()</code> 은 list에 얼음을 걸어서 읽기전용인 튜플로 만들고, <code>list()</code>는 꼼짝없이 얼어붙어있던 읽기 전용 튜플을 읽기 쓰기가 가능한 list로 만들어 줍니다.
</blockquote>
<h3 id=tuples-in-a-boolean-context>튜플로 참, 거짓 판단하기</h3>
<p>
<code>if</code>문과 같이 <a href=#booleans>참, 거짓을 판별하는 구문</a>에서도 튜플을 사용할 수 있습니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>def is_it_true(anything):</kbd>
<samp class=p>... </samp><kbd class=pp> if anything:</kbd>
<samp class=p>... </samp><kbd class=pp> print("yes, it's true")</kbd>
<samp class=p>... </samp><kbd class=pp> else:</kbd>
<samp class=p>... </samp><kbd class=pp> print("no, it's false")</kbd>
<samp class=p>...</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(())</kbd> <span class=u>①</span></a>
<samp>no, it's false</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true(('a', 'b'))</kbd> <span class=u>②</span></a>
<samp>yes, it's true</samp>
<a><samp class=p>>>> </samp><kbd class=pp>is_it_true((False,))</kbd> <span class=u>③</span></a>
<samp>yes, it's true</samp>
<a><samp class=p>>>> </samp><kbd class=pp>type((False))</kbd> <span class=u>④</span></a>
<samp class=pp><class 'bool'></samp>
<samp class=p>>>> </samp><kbd class=pp>type((False,))</kbd>
<samp class=pp><class 'tuple'></samp></pre>
<ol>
<li>
빈 튜플은 false를 의미합니다.
<li>
튜플내에 원소가 하나라도 있으면 true 입니다.
<li>
튜플내에 원소가 하나라도 있으면 true 입니다. 원소의 값이 무엇인지는 상관없고요. 그건 그렇고 콤마는 무슨뜻일까요?
<li>
원소가 하나뿐인 튜플을 만들때는 그 원소뒤에 콤마를 써줘야 합니다. 콤마가 없으면 파이썬은 그냥 괄호가 두번 연달아 사용됬다고 인식할 뿐, 그중 하나가 튜플이라고 판단하지 못합니다.
</ol>
<h3 id=multivar>여러 값을 한꺼번에 할당하기</h3>
<p>파이썬 튜플이 가진 멋진 기능중 하나는, 여러 값을 한꺼 번에 할당해야 하는 상황에서 튜플을 사용할 수 있다는 점입니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>v = ('a', 2, True)</kbd>
<a><samp class=p>>>> </samp><kbd>(x, y, z) = v</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>x</kbd>
<samp class=pp>'a'</samp>
<samp class=p>>>> </samp><kbd class=pp>y</kbd>
<samp class=pp>2</samp>
<samp class=p>>>> </samp><kbd class=pp>z</kbd>
<samp class=pp>True</samp></pre>
<ol>
<li>
<var>v</var> 는 세 개의 원소로 이루어진 튜플입니다. <code>(x, y, z)</code> 는 세 개의 변수를 가진 튜플이구요. 서로 짝이 맞기 때문에 한쪽에서 다른 쪽으로 할당하면, 변수가 선언된 순서대로 할당이 이루어집니다.
</ol>
<p>
튜플의 이런 특징은 꽤 쓸모가 많습니다. 일례로 특정 범위 내에 있는 값들을 변수들에 할당해야 할 때, 파이썬 내장함수인 <code>range()</code> 와 튜플을 함께 사용하여 간단하게 해결할 수 있습니다. 아래 예제코드를 보시죠.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>MONDAY</kbd> <span class=u>②</span></a>
<samp class=pp>0</samp>
<samp class=p>>>> </samp><kbd class=pp>TUESDAY</kbd>
<samp class=pp>1</samp>
<samp class=p>>>> </samp><kbd class=pp>SUNDAY</kbd>
<samp class=pp>6</samp></pre>
<ol>
<li>
내장함수 <code>range()</code> 는 일련의 정수들을 만들어 냅니다. (정확히 말하면 <code>range()</code> 는 list나 tuple이 아닌 <a href=iterators.html>반복자(iterator)</a>를 반환합니다. 이들의 차이점은 뒤에서 따로 다룰겁니다) <var>MONDAY</var>, <var>TUESDAY</var>, <var>WEDNESDAY</var>, <var>THURSDAY</var>, <var>FRIDAY</var>, <var>SATURDAY</var>, and <var>SUNDAY</var> 와 같은 변수들을 정의했고요.
(이 예제 코드는 사실 <code>calendar</code> 모듈에서 가져왔습니다. 이 모듈은 달력과 관련된 기능들을 모아둔 모듈인데요, <abbr>UNIX</abbr> 운영체제를 보면<code>cal</code> 이라고 하는 날짜를 출력하는 프로그램이 있는데, 이와 비슷한 기능을 가진 모듈입니다. 이 <code>calendar</code> 모듈은 월요일부터 일요일까지를 정수의 상수값으로 정의해두고 있습니다.)
<li>
자 이제 모든 변수가 값을 갖게되었습니다. <var>MONDAY</var> 는 0, <var>TUESDAY</var> 는 <code>1</code>, 이런식으로 값이 할당됩니다.
</ol>
<p>
튜플을 이용하면 둘 이상의 값을 인자로 받아, 둘 이상의 값을 반환하도록 하는 함수도 작성할 수 있습니다. 여러 값들을 묶어서 하나의 튜플 변수로 처리하면 되니까요. 실제로 파이썬 표준 라이브러리의 수 많은 함수들이 이 테크닉을 즐겨 이용하고 있답니다. (궁금하신 분은 <code>os</code> 모듈 소스코드를 들여다 보세요.)
<p class=a>⁂
<h2 id=sets>Sets</h2>
<p>
<dfn>set</dfn>은 마치 유일한 값을 가진 데이터들을 뒤죽박죽인 채로 넣어둔 자루와 같습니다. set 안에 들어갈 수 있는 데이터는 추후 변경이 불가능 (immutable) 해야 합니다. 두 개의 set 이 정의되 있다면, 마치 수학에서의 합집합 (union), 교집합 (intersection) 그리고 교집합을 제외한 나머지 (difference) 등과 같은 개념을 표준 set 함수를 이용해 구할 수 있습니다.
<h3 id=creating-a-set>Set 생성</h3>
<p>
먼저 set 을 만들어봅시다. 간단합니다.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>a_set = {1}</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>type(a_set)</kbd> <span class=u>②</span></a>
<samp class=pp><class 'set'></samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_set = {1, 2}</kbd> <span class=u>③</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2}</samp></pre>
<ol>
<li>
어떤 하나의 값을 가지고 set을 만드는 경우엔, 그 값 주변을 코드에서와 같이 curly brace (<code>{}</code>)로 감싸주면 됩니다.
<li>
set의 타입은 <a href=iterators.html#defining-classes>클래스</a>입니다. 클래스에 대해서는 나중에 따로 설명해 드리겠습니다. 걱정마세요.
<li>
두 개 이상의 값을 가지고 set을 만드는 경우엔, 각각의 값들 사이에 콤마를 넣어주고, curly brace (<code>{}</code>)로 감싸주면 됩니다.
</ol>
<p>
<a href=#lists>list</a>를 set으로 변환할 수도 있습니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_list = ['a', 'b', 'mpilgrim', True, False, 42]</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_set = set(a_list)</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>a_set</kbd> <span class=u>②</span></a>
<samp class=pp>{'a', False, 'b', True, 'mpilgrim', 42}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_list</kbd> <span class=u>③</span></a>
<samp class=pp>['a', 'b', 'mpilgrim', True, False, 42]</samp></pre>
<ol>
<li>
list를 set으로 변환할때는 <code>set()</code>함수를 사용하면 됩니다. 혹시 어떤 깐깐한 분들께서는 "잠깐만요, 이건 사실 함수호출이 아니라 객체 생성 (class instantiation) 아닌가요?" 라고 질문하실수도 있겠습니다. 약속드릴게요. 제가 나중에 다시 설명드리겠습니다. 일단 지금은 <code>set()</code> 이 함수처럼 동작하고, set 을 반환한다고 알고 넘어갑시다.
<li>
set 내부에는 어떤 데이터 타입도 포함될 수 있다고 말씀드렸죠? 그리고 뒤죽박죽인 채로 (<em>unordered</em>) 들어있다고 말한것도 기억하시나요? 비록 이 set 은 list 를 이용해 생성되었지만, list 에 들어있던 원소들의 순서는 깡그리 무시됩니다. 그리고 또 다른 아이템들을 이 set 안에 추가하더라도, 추가되는 순서또한 무시된다는 걸 기억하세요.
<li>
원본 list 는 그대로 있습니다.
</ol>
<p id=emptyset>
set 안에 집어넣을 아이템이 아직 준비되지 않았다구요? 괜찮습니다. 빈 set을 만들면 되거든요.
<pre class=screen>
<a><samp class=p>>>> </samp><kbd class=pp>a_set = set()</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>a_set</kbd> <span class=u>②</span></a>
<samp class=pp>set()</samp>
<a><samp class=p>>>> </samp><kbd class=pp>type(a_set)</kbd> <span class=u>③</span></a>
<samp class=pp><class 'set'></samp>
<a><samp class=p>>>> </samp><kbd class=pp>len(a_set)</kbd> <span class=u>④</span></a>
<samp class=pp>0</samp>
<a><samp class=p>>>> </samp><kbd class=pp>not_sure = {}</kbd> <span class=u>⑤</span></a>
<samp class=p>>>> </samp><kbd class=pp>type(not_sure)</kbd>
<samp class=pp><class 'dict'></samp></pre>
<ol>
<li>
To create an empty set, call <code>set()</code> with no arguments.
빈 set 을 만드려면 <code>set()</code>라고 입력합니다. 함수안에 어떤 인자도 주지 않습니다.
<li>
비어있는 set을 출력하면 좀 의외의 결과가 나오죠? 뭐 <code>{}</code> 랑 비슷한 것이 나와야 하지 않을까라고 생각하셨을지도 모르겠습니다. 하지만 <code>{}</code> 는 빈 dictionary 를 의미합니다. dictionary 에 대해서는 조금있다가 배우도록 하겠습니다.
<li>
어찌됬던 간에 이게 바로 set입니다…
<li>
…그리고 텅텅 비어있는 set이죠.
<li>
Python 2에서 정의된 룰을 따르다 보니, curly brace 로는 빈 set이 아닌 빈 dictionary를 만들게 됩니다.
</ol>
<h3 id=modifying-sets>Set 변경하기</h3>
<p>
set에 새로운 아이템을 추가하는 데는 두 가지 방법이 있습니다. 하나는 <code>add()</code> 메소드를 호출하는 것이고, 다른 하나는 <code>update()</code> 메소드를 호출하는 겁니다.
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_set = {1, 2}</kbd>
<a><samp class=p>>>> </samp><kbd class=pp>a_set.add(4)</kbd> <span class=u>①</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2, 4}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>len(a_set)</kbd> <span class=u>②</span></a>
<samp class=pp>3</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_set.add(1)</kbd> <span class=u>③</span></a>
<samp class=pp>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2, 4}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>len(a_set)</kbd> <span class=u>④</span></a>
<samp class=pp>3</samp></pre>
<ol>
<li>
<code>add()</code> 메소드는 하나의 인자를 받습니다. 어떤 데이터 타입이든 상관없이 그 인자를 주어진 set에 추가합니다.
<li>
이제 이 set은 3개의 아이템을 가지게 되었습니다.
<li>
set 은 유일한 값들을 집합이라고 말씀드렸습니다. 만약 중복되는 아이템을 추가하면 아무일도 생기지 않습니다. 에러도 생기지 않구요, 그냥 아무 일도 안 일어납니다.
<li>
여전히 3개의 아이템을 가지고 있습니다.
</ol>
<pre class=screen>
<samp class=p>>>> </samp><kbd class=pp>a_set = {1, 2, 3}</kbd>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2, 3}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_set.update({2, 4, 6})</kbd> <span class=u>①</span></a>
<a><samp class=p>>>> </samp><kbd class=pp>a_set</kbd> <span class=u>②</span></a>
<samp class=pp>{1, 2, 3, 4, 6}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_set.update({3, 6, 9}, {1, 2, 3, 5, 8, 13})</kbd> <span class=u>③</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2, 3, 4, 5, 6, 8, 9, 13}</samp>
<a><samp class=p>>>> </samp><kbd class=pp>a_set.update([10, 20, 30])</kbd> <span class=u>④</span></a>
<samp class=p>>>> </samp><kbd class=pp>a_set</kbd>
<samp class=pp>{1, 2, 3, 4, 5, 6, 8, 9, 10, 13, 20, 30}</samp></pre>
<ol>
<li>
예제 코드에서 <code>update()</code> 메소드는 하나의 인자를 입력으로 받았는데, 그 인자 역시 set 이군요. 이 코드는 입력으로 주어진 set 을 대상이 되는 set에 추가합니다. 입력 set 내 아이템들 하나 하나에 <code>add()</code> 메소드를 호출하는 것과 같은 동작을 합니다.
<li>
set 은 유일한 값만 받아들이므로 중복되는 값은 추가되지 않습니다.
<li>
<code>update()</code> 메소드의 인자로 두 개 이상의 set 을 전달하는 것도 가능합니다. 타겟 set 내 아이템과 중복되는 것은 무시하고, 모든 아이템을 타겟 set 에 추가합니다.
<li>
<code>update()</code> 메소드는 인자로 어떤 데이터 타입도 넘겨줄 수 있습니다. 예제에서는 인자의 타입으로 list를 넘겨주고 있습니다. list가 인자로 건네지면 list 내 모든 아이템을 타겟 set에 추가하게 됩니다.
</ol>
<h3 id=removing-from-sets>Set 아이템 삭제하기</h3>