-
Python Programming (5) - 리스트Python Programming 2020. 3. 28. 06:50728x90
5.Python_List_Dictionary 5. List and Dictionary¶
List¶
[ ]
와,
로 표현하는 데이터 형으로 여러 가지 형태의 정보를 하나의 리스트로 묶어서 나타냄
In [1]:squares = [1, 4, 9, 16, 25] zoo_animal = ['tiger', 'lion', 'monkey'] smith_information = ['Smith', 1990, 'London'] lee_information = ['Lee', 1975, 'Seoul'] customer = [smith_information, lee_information]
- len() 함수를 이용하여 길이를 구함
In [2]:len(squares)
Out[2]:In [3]:len(zoo_animal)
Out[3]:In [4]:len(customer)
Out[4]:List의 인덱스(index)¶
In [5]:squares = [1, 4, 9, 16, 25, 36, 49, 64, 81]
- index를 이용한 list 접근
- 첫 아이템의 index는 0부터 시작
In [6]:squares[0]
Out[6]:In [7]:squares[1]
Out[7]:In [8]:squares[4]
Out[8]:list의 slice 연산¶
In [9]:squares = [1, 4, 9, 16, 25, 36, 49, 64, 81]
In [10]:squares[0:3]
Out[10]:혹은
In [11]:squares[:3]
Out[11]:- 인덱스 0의 item부터 인덱스 3의 item 이전까지
In [12]:squares[3:6]
Out[12]:- 인덱스 3의 item부터 인덱스 6의 item 이전까지
In [13]:squares[6:9]
Out[13]:혹은
In [14]:squares[6:]
Out[14]:- 인덱스 0의 item부터 인덱스 6의 item 이전까지 2의 간격으로
In [15]:squares[0:6:2]
Out[15]:list 내용 변경¶
In [16]:squares = [1, 4, 10, 17, 25]
In [17]:squares[2] = 9 print(squares)
In [18]:squares[3] = 16 print(squares)
In [19]:squares = [1, 4, 10, 17, 25] print(squares)
In [20]:squares[2:4] = [9, 16] print(squares)
In [21]:squares = squares + [36, 49, 64] print(squares)
In [22]:squares.append(81) print(squares)
In [23]:squares.append(10**2) print(squares)
In [24]:squares[5:10] = [] print(squares)
In [25]:squares[1] = [] print(squares)
In [26]:squares[1:2] = [] print(squares)
In [27]:squares.insert(1, 4) print(squares)
list내의 list¶
In [28]:A = [[0,1,2,3,4], ['a', 'b']]
In [29]:A[0]
Out[29]:In [30]:A[1]
Out[30]:In [31]:A[0][0]
Out[31]:In [32]:A[0][1]
Out[32]:In [33]:A[1][0]
Out[33]:In [34]:A[1][1]
Out[34]:list의 다양한 method¶
In [35]:animals = ['dog', 'cat', 'duck', 'lion', 'snake']
In [36]:animals.index('cat')
Out[36]:In [37]:animals.remove('duck') animals
Out[37]:- list data type은 다양한 method들을 포함하며 아래의 링크에서 확인
- https://docs.python.org/2/tutorial/datastructures.html#more-on-lists
참조와 복사¶
- 하나의 객체를 L1, L2가 동시에 지칭하여, L1의 원소가 변하면 L2의 원소도 같이 변함
In [38]:L1 = [1, 2, 3] L2 = L1 L1[0] = 4
In [39]:print(L1)
In [40]:print(L2)
- L1에 새로운 리스트를 대응하면 원래의 참조를 끊고 새로운 대입값을 적용
In [41]:L1 = [1, 2, 3] L2 = L1 L1 = [4, 5, 6]
In [42]:print(L1)
In [43]:print(L2)
- 같은 대상을 참조하는 것이 아니라 대상을 복사하여 사용하고 싶을 때
- 복사는 얕은 복사와 깊은 복사가 있으며 우리 과정에서는 얕은 복사만 다룬다.
In [11]:L1 = [1, 2, 3] L2 = L1[:] #python2에서 많이 쓰던 방법
혹은
In [3]:L2 = list(L1)
혹은
In [5]:# Python3에서 가장 추천하는 방법 L2 = L1.copy()
In [6]:L1[0] = 4 print(L1)
In [7]:print(L2)
복사의 예¶
- Python 언어의 모든 매개 변수는 참조로 전달된다.
- 즉, 함수 내에서 매개 변수가 참조하는 것을 변경하면 변경 내용은 호출 함수 밖에서도 반영된다.
- 이를 pass by reference(참조)라고 한다.
- 다음 예제를 보면 함수 내부에서 변화가 함수 바깥으로 영향을 미치는 것을 볼 수 있다.
In [48]:def changeme(mylist): mylist.append([1,2,3,4]) print("Values inside the function: ", mylist) return mylist = [10,20,30] changeme(mylist) print("Values outside the function: ", mylist)
- 만약 이를 원치 않으면, 다음과 같이 복사하여 사용한다.
In [8]:def changeme(mylist): mylist = mylist.copy() mylist.append([1,2,3,4]) print("Values inside the function: ", mylist) return mylist = [10,20,30] changeme(mylist) print("Values outside the function: ", mylist)
복사의 예(2)¶
아래에서
removeDup
은L1
과L2
를 비교하여, 중복되는 항목을L1
에서 제거하는 목적을 지닌다.
다음의 두removeDup
를 비교해 보자.In [1]:# 정상적으로 삭제되지 않는 경우 def removeDup(L1, L2): for e1 in L1: if e1 in L2: L1.remove(e1) L1=[1,2,3,4] L2=[1,2,5,6] removeDup(L1, L2) print('L1 = ', L1)
In [9]:# 복사 [:]를 사용하여 정상적으로 고칠 수 있다. def removeDup(L1, L2): for e1 in L1.copy(): if e1 in L2: L1.remove(e1) L1=[1,2,3,4] L2=[1,2,5,6] removeDup(L1, L2) print('L1 = ', L1)
첫 코드의 문제는
for
문 내에서L1
이 변한다는 것이다.
함수가 아닌for
문만을 통해 표현해도 똑같은 문제점을 발견할 수 있다.In [3]:L1=[1,2,3,4] L2=[1,2,5,6] for e1 in L1: if e1 in L2: L1.remove(e1) print('L1 = ', L1)
In [10]:L1=[1,2,3,4] L2=[1,2,5,6] for e1 in L1.copy(): if e1 in L2: L1.remove(e1) print('L1 = ', L1)
string과 list의 차이점¶
- string과 list는 인덱스를 통해 접근할 수 있는 등 비슷한 점이 많음
In [52]:my_string = 'test' print(my_string[0])
- list는 인덱스를 통해 원소를 변화시키는 것이 가능(mutable)
- my_list[i] = new_element
- string은 불가능 (immutable)
In [53]:my_string[0] = 'k'
list concatenation¶
In [54]:x = [1, 2, 3] x.extend([4, 5, 6]) # x is now [1, 2, 3, 4, 5, 6] print(x)
만약 x를 변화시키고 싶지 않으면
In [55]:x = [1, 2, 3] y = x + [4, 5, 6] # y is [1, 2, 3, 4, 5, 6] x는 그대로 print(x) print(y)
- 하나씩 추가할 경우는 append를 많이 씀
In [56]:x = [1, 2, 3] x.append(0) # x is now [1, 2, 3, 0] print(x)
List comprehension¶
In [57]:squares = [x**2 for x in range(4)] print(squares)
In [58]:[(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x!=y]
Out[58]:In [59]:[abs(x) for x in [-1, 2, -3]]
Out[59]:In [60]:from math import pi [str(round(pi, i)) for i in range(1, 6)]
Out[60]:In [61]:mixed = [1, 2, 'a', 3, 4.0] print([x**2 for x in mixed if type(x) == int])
Tuple - 투플¶
- Tuple은 list와 매우 비슷함
- 단 immutable
- 내용을 바꾸는 연산을 제외한 list의 많은 연산을 똑같이 수행 가능
- [ ]가 아닌 ( ) 혹은 아무런 괄호 없이 표현
In [62]:my_tuple = (1, 2) my_tuple[1] = 3
- 여러 값을 같이 반환할 때 유용
In [63]:def sum_product(x, y): return x+y, x*y
In [64]:sum_product(2, 3)
Out[64]:- 여러 값을 동시에 부여 (list로도 가능)
In [65]:x, y = (1, 2) x, y = y, x #Python에서 두 변수 값을 swap하는 법 print(x, y)
Example : Tuple¶
In [66]:t1 = () t2 = (1, 'two', 3) t3 = (10,) # 원소가 하나인 tuple
In [67]:print(t1)
In [68]:print(t2)
In [69]:print(t3)
In [70]:t1 = (1, 'two', 3) t2 = (t1, 3.25)
In [71]:print(t2)
In [72]:print(t1 + t2)
In [73]:print((t1 + t2)[3])
In [74]:print((t1 + t2)[2:5])
Example : 공약수¶
In [75]:def findDivisors (n1, n2): divisors = () #empty tuple for i in range(1, min (n1, n2) + 1): if n1%i == 0 and n2%i == 0: divisors = divisors + (i, ) return divisors
In [76]:divisors = findDivisors(20, 100) print(divisors)
for문과 list의 연계¶
In [77]:my_list = [10, 'hi', -1.2, 'first']
In [78]:for x in my_list: print(x)
In [79]:student_list = ['Tom', 'Jack', 'Jane', 'Susan'] student_list.sort() for student in student_list: print(student)
Iterables¶
- iterable 혹은 interable container는 한 번에 하나씩 멤버를 반환할 수 있는 모든 Python 객체로서
for
루프에서 반복을 사용할 수 있도록 한다.- for loop에서 활용될 때 Python 내부적으로는
iter()
함수를 이용하여 Iterator라는 객체로 변환하여 사용한다. - Iterator는
next()
함수를 이용하여 다음 멤버를 반환할 수 있음
- for loop에서 활용될 때 Python 내부적으로는
- list, tuples, string, dictionary 등이 있다.
In [80]:student_list = ['Tom', 'Jack', 'Jane', 'Susan'] iterator_obj = iter(student_list) print(next(iterator_obj)) print(next(iterator_obj)) print(next(iterator_obj)) print(next(iterator_obj))
In [81]:# 다음의 두 코드는 같은 역할을 수행한다.. for x in [1,2]: print(x) for x in iter([1,2]): print(x)
Generator¶
- List의 문제 중 하나는 그 길이가 매우 커질 수 있다는 점.
- 예를 들어 Python2에서
range(1000000)
은 백만 개의 원소를 가지는 list. (Python3에서는 list가 아님)- 때로는 단순히 for문을 돌리기 위해 이 데이터를 모두 생성하여 메모리에 저장하는 것은 낭비일 수 있음.
- Generator는 iterator의 특별한 종류로, 각 멤버를 생성하는 방법을 저장한 후, 반복을 통해 요청될 때만 각 멤버를 한 번에 하나씩 생성한다.
- Python3에서는
for
문에서range(1000000)
가 generator를 통해 활용된다.for
문 등을 이용하여 반복 가능하지만, 그 값들을 생성하는 것은 필요한 경우만 실행.range()
자체는 generator는 아니지만for
문에서 활용될 때는 generator로 변환하여 실행됨.
- Python2에서는 이와 같은 역할을 하는
xrange
라 불리우는 함수가 있음
In [46]:# range()를 list처럼 합치면 예상치 못한 결과가 나올 수 있음 for i in range(3) + range(3,6): print(i)
In [102]:# list로 변환하여 해결하는 방안이 있음 for i in list(range(3)) + list(range(3,6)): print(i)
In [103]:list(range(4)) + list(range(5))
Out[103]:[0, 1, 2, 3, 4]
와range(5)
의 차이:¶Python3에서는
range(5)
는 숫자 0-4의 수열을 생성하는 데 필요한 명령을 저장하지만, list[0, 1, 2, 3, 4]
은 속해 있는 모든 값을 메모리에 저장한다.- Python2에서는
[0, 1, 2, 3, 4]
와range(5)
는 같다.
In [1]:# Python 3에서 range(5)로 [0,1,2,3,4]를 생성할 수 있지만, 실제로 [0,1,2,3,4]와 같은 것은 아니다. print(range(5))
In [2]:print([0,1,2,3,4])
generator 만들기¶
- generator는
return
대신yield
키워드를 이용하면 만들 수 있다. - generator의 특성상 무한한 값을 생성하는 것도 가능하다.
In [4]:def even_numbers(): n = 1 while True: if (n % 2 == 0): yield n n += 1
In [5]:even_numbers()
Out[5]:In [6]:g = even_numbers() print(next(g)) print(next(g)) print(next(g))
In [7]:for i in even_numbers(): print(i, end=" ") if (i >= 100): break #break가 없으면 무한 루프 생성
enumerate¶
- enumerate을 이용하여 인덱스와 리스트의 값에 접근할 수 있다.
- (index, value)로 이루어진 (generator와 매우 흡사한) iterator를 반환하여
for
문 등에서 사용 가능 - list로 변환하여 활용하려면
list()
를 이용
In [18]:student_list = ['Tom', 'Jane', 'Susie', 'Chris'] for index, value in enumerate(student_list): print(index, value)
In [19]:enumerate(student_list)
Out[19]:In [20]:seasons = ['Spring', 'Summer', 'Fall', 'Winter'] list(enumerate(seasons))
Out[20]:list의 index를 기반으로 for문을 활용하려면 크게 다음의 두 가지 방법이 있다.
두 방법은 같은 효과를 가지며 어떤 것을 활용해도 상관은 없지만 Python에서는 두 번째 방법을 많이 사용한다.
for i in range(len(some_list)):
do something(i) # not Pythonicfor i, _ in enumerate(some_list) :
do something(i) # Pythonic
zip¶
- 두 개 이상의 리스트를 원소 별로 합쳐서 tuple들의 iterator로 생성
enumerate
과 마찬가지로 generator와 흡사한 성질을 지님
- iterator로 만들어지기 때문에 실체를 확인하려면
list()
를 이용하여 list로 만들어 확인
In [41]:x = [1, 2, 3] y = [4, 5, 6] zipped = zip(x, y) # iterator for [(1, 4), (2, 5), (3, 6)] print(zipped)
In [42]:for z in zipped: print(z)
In [43]:# iterator zipped가 한 바퀴 돌았기 때문에, 빈 list가 생성된다. print(list(zipped))
In [44]:# Do zip again. x = [1, 2, 3] y = [4, 5, 6] zipped = zip(x, y) # iterator for [(1, 4), (2, 5), (3, 6)] print(list(zipped))
In [45]:list(zip([1, 2, 3], [4, 5, 6], [7, 8, 9]))
Out[45]:String, tuple, list 공통적인 기능¶
seq[i]
: i번째 원소len(seq)
: 길이seq1 + seq2
: 연결n * seq
: n번 반복seq[start:end]
: 일부e in seq
: 만약 e가 seq에 속하면 True, 아니면 Falsee not in seq
: 만약 e가 seq에 속하면 False, 아니면 Truefor e in seq
: 반복문
Sorting - 정렬¶
- Python 리스트는 sort method를 이용하여 정렬 가능
In [129]:x = [4, 1, 2, 3] y = sorted(x) # y는 [1, 2, 3, 4], x는 변하지 않음 print(x) print(y)
In [130]:x.sort() # x가 이제 [1, 2, 3, 4] print(x)
- 응용 : 절대값 기준으로 내림차순으로 정렬
In [131]:x = sorted([-4, 1, -2, 3], key=abs, reverse=True) print(x)
랜덤 (random) 리스트¶
아래 예제는 0과 1사이의 임의의 실수를 랜덤하게 4번 생성하여 리스트로 만들고자 한다.
random.random()
은 0과 1사이에서 uniform하게 분포된 랜덤 숫자를 반환_
는 다시 사용하지 않을 dummy variable을 표현x
로 바꾸어도 상관없음
In [22]:import random four_uniform_randoms = [random.random() for _ in range(4)] print(four_uniform_randoms)
랜덤 샘플 추출 (중복 허용하지 않음)
- 0이상 60미만의 정수 중 중복을 허용하지 않고 6개의 랜덤 샘플을 추출
In [23]:lottery_numbers = range(60) random.sample(lottery_numbers, 6) # 6개의 랜덤 샘플
Out[23]:랜덤 선택 (중복 허용)
- 0이상 10미만의 수를 중복하용하여 4번 추출
random.choice()
는 주어진 값들 중 임의의 하나의 값을 선택
In [26]:four_with_replacement = [random.choice(range(10)) for _ in range(4)] print(four_with_replacement)
Dictionary¶
- key : value 형태의 대응 관계를 나타내는 자료형
- Dictionary는 list처럼 여러 원소들을 하나의 collection으로 사용
- List에서는 index를 통하여 원소에 접근하였지만, dictionary에서는 key를 통하여 접근
- Dictionary의 기본 구조
{key1: element1, key2: element2, … }
- key는 일반적으로 string이나 숫자를 사용
- 예제 – 학생 이름과 점수
{'Tom': 92, 'Jane': 95, 'Amy': 73, 'Nick': 81}
- 학생 이름이 key로 사용되었으며, 점수가 값으로 사용됨
- 예제 – 학생 이름과 점수
- dictionary는 key의 순서가 중요하지 않음(unordered)
key를 통한 접근¶
In [3]:scores = {'Tom': 92, 'Jane': 95, 'Amy': 73, 'Nick': 81}
In [4]:scores['Tom']
Out[4]:In [5]:scores[0] # error 발생 : index를 통해 접근할 수 없음
- list에서와 같이 key를 통하여 원소의 내용을 바꿀 수 있음 (mutable)
In [6]:scores['Tom'] = 100 print(scores)
- 기존에 'Robin'이 없으므로 새로운 원소 추가
In [7]:scores['Robin'] = 50 print(scores)
- 기존의 원소 제거
In [8]:del scores['Nick'] print(scores)
유용한 method들¶
In [9]:scores.keys()
Out[9]:In [10]:scores.values()
Out[10]:In [11]:scores.items()
Out[11]:dictionanry를 이용한 for¶
dictionary를 직접
for
문에 이용하면 key를 바탕으로for
문이 실행된다.In [12]:for key in scores: print(key, scores[key])
비슷한 방법으로는
.keys()
method를 이용할 수 있으나, 위의 방법이 더 선호되는 경향이 있음In [14]:for key in scores.keys(): print(key, scores[key])
key와 value를 모두 필요로 할 때는
.items()
를 이용한다. 따라서 위의 코드들은 아래처럼 이용하는 것이 효율적이다.- 가장 활용도가 높고 효율이 좋음
- list에서
enumerate()
과 비슷한 역할
In [15]:for k, v in scores.items(): print(k, v)
In [19]:knights = {'gallahad': 'the pure', 'robin': 'the brave'} for k, v in knights.items(): print(k, v)
만약 value만 필요하다면 key 부분은
_
로 받을 수 있다.In [16]:# 점수 총합을 계산 sum_score = 0 for _, v in scores.items(): sum_score += v print(sum_score)
물론
.values()
를 이용할 수도 있음In [18]:sum_score = 0 for v in scores.values(): sum_score += v print(sum_score)
구조화된 데이터를 dictionary로 표현¶
In [119]:tweet = { "user" : "joelgrus", "text" : "Data Science is Awesome", "retweet_cout" : 100, "hashtags" : ["#data", "#science"] } tweet_keys = tweet.keys() # sequence of keys tweet_values = tweet.values() # sequence of values tweet_items = tweet.items() # sequence of (key, values)
In [120]:tweet_keys
Out[120]:In [121]:tweet_values
Out[121]:In [122]:tweet_items
Out[122]:In [123]:"user" in tweet_keys # True but slow
Out[123]:In [124]:"user" in tweet # True faster
Out[124]:In [125]:"joelgrus" in tweet_values #True
Out[125]:Counter¶
- sequence를 dictionary와 비슷한 형태로 바꾸어 줌
In [28]:from collections import Counter c = Counter([0, 1, 2, 0]) print(c)
c
의 결과는 다음과 같다 :Counter({0: 2, 1: 1, 2: 1})
- 0이 2개, 1이 1개, 2가 1개 있음을 나타냄
In [29]:c2 = Counter(["a", "b", "a", "c", "b", "a"]) print(c2)
728x90'Python Programming' 카테고리의 다른 글
Python Programming (7) - 데이터 시각화 (0) 2020.03.28 Python Programming (6) - 선형대수 (0) 2020.03.28 Python Programming (4) - 함수 (0) 2020.03.28 Python Programming (3) - 반복문 (0) 2020.03.28 Python Programming (2) - 조건문 (0) 2020.03.28