728x90
반응형

 이전 포스트에선 빅데이터 분석을 하며 눈에 익었던 Python Type이 무엇이 있는지와 그중 하나인 Scalar에 대해 간략하게 알아보았다. 이번 포스트에서는 list에 대해 이야기해보자.

 

 

list

# list는 Data를 담는 가장 기본적인 상자라고 생각하자
# list는 다음과 같은 방법으로 만들 수 있다.
# 1. [] 사용하기
>>> list1 = [1, 2, 3, 4, 5, 6, 7]
>>> print(list1)
[1, 2, 3, 4, 5, 6, 7]

# 2. list() 함수 사용하기
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • list는 파이썬에서 가장 일반적인 데이터를 담는 type이다.
  • scalar(int, float, None, Boolean)뿐만 아니라 문자형(str)도 담을 수 있다.
  • 연산에 특화된 Type이 아닌 데이터를 담는 기본 그릇이라고 생각하는 것이 이해하기 쉽다.
  • list는 list() 함수, [] 안에 넣고자하는 Data를 넣어서 만들 수 있다.

 

Range

# range는 무엇인가?
>>> print(range(10))
range(0, 10)

# for문을 사용하여 range의 인자들을 출력해보자
>>> for i in range(10):
>>>    print(i)
0
1
2
3
4
5
6
7
8
9

# range()함수는 range(시작, 끝, 간격)으로 값을 내가 원하는 때에 호출할 수 있는 함수다.
>>> [i for i in range(4, 20, 2)]
[4, 6, 8, 10, 12, 14, 16, 18]
  • range() 함수는 꽤 자주 쓰이는 함수로, list와 꽤 친하니 이참에 설명하고 가겠다.
  • range(시작 값, 끝 값, 간격)을 입력하여 내가 원하는 패턴을 갖는 임의의 데이터를 생성할 수 있다.
  • 중요사항!) list에 data를 담는 경우, 그 data를 전부 생성해버리기 때문에 list를 생성하는 순간부터 memory를 쭉 잡아먹지만, range() 함수는 내가 원할 때, 그 값을 가지고 오기 때문에 memory 낭비가 발생하지 않는다.
    1. range() 함수를 출력하는 경우 range()라는 객체가 반환된다.
      • 객체란? 아주 단순하게 설명해보자면, X라는 함수를 통해 무언가를 만들어냈으나, 그 결과물이 가지고 있는 정보가 매우 다양해서 한 번에 다 보는 것이 어려운 상태이다.
      • 이 결과물에 특정 스위치를 붙이고 스위치를 켜주면, 그에 해당하는 정보를 볼 수 있다.
      • 즉, "내가 보여줄 수 있는 것은 아주 많은데, 뭘 원해?"라고 물어보고 있는 상태라고 생각하면 쉽다.
    2.  range() 함수로 생성된 range 객체는 당장 값이 나오지 않으며, for문과 같은 기능을 실행해주어야, 값을 반환한다.
      • 내가 원할 때, 값을 가지고 온다(for문을 실행)는 것은 제네레이터(Generator)와 유사해보이지만, range()는 엄밀히 따지면 Genarator가 아니다.
      • next() 함수를 이용해서 값을 꺼내면 오류가 발생한다.
      • 이는 추후 제네레이터를 설명할 때 다시 언급하도록 하겠다.

 

 

 

list의 연산

>>> a = [1,2,3,4]
>>> b = [5,6,7]
>>> print(a + b)
[1, 2, 3, 4, 5, 6, 7]


>>> print(a * b)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-f9c8a447c001> in <module>
----> 1 print(a*b)

TypeError: cant multiply sequence by non-int of type "list"


>>> print(a * 3)
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
  • Data가 담기는 그릇인 list는 연산보다는 Data를 담는 것이 주목적이다 보니 우리가 생각하는 연산과 다른 결과가 출력된다.
  • list와 list를 더 하면 두 list의 값이 합쳐지는(sum)것이 아닌 한 그릇으로 합쳐진다(extend).
  • list와 list의 곱은 데이터가 담긴 두 그릇을 곱하는 것이니 연산되지 않는다.
  • list에 int를 곱하면 데이터가 담긴 그릇을 그 int만큼 더 추가한다.
  • 이는 list가 연산이 아닌 데이터를 담는 그릇의 성질이 더 강하다는 것을 뜻한다. 때문에 list에는 숫자형과 문자형을 함께 담을 수도 있으며, 함께 담는다고 해서 데이터의 타입이 자동으로 바뀌지 않는다.

 

 

 

list의 인덱싱(슬라이싱)

# 내가 원하는 위치에 있는 값을 가지고 올 수 있다.
>>> c = list(range(20))
>>> print(c[3])
3
>>> print(c[5:12])
[5, 6, 7, 8, 9, 10, 11]

# list의 안에는 다른 list를 담을수도 있다!
>>> d = [3,5,7,['a', 'p', 'p', 'l', 'e']]
>>> print(d[3])
['a', 'p', 'p', 'l', 'e']
>>> print(d[3][3:])
['l', 'e']
  • Data를 담는 그릇인 list는 아주 쉽게 내가 원하는 위치에 있는 데이터를 가지고 올 수 있다.
  • list[위치]를 이용하면 그 위치에 있는 값을 가지고 온다.
  • Data를 담는 그릇인 list는 list 안에 list를 담을 수 있는데, 안에 있는 list를 가지고 오고 그 list 안에서 원하는 위치를 지정하면 똑같이 가져올 수 있다.
  • :는 가져오려는 index의 구간을 정해줄 수 있다.
# list에서 특정 조건에 맞는 값을 가지고 오기.
>>> print(c)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]


# 1. list c에서 10 이상인 값들을 가지고 와보자.
>>> c >= 10
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-36-0a29ddccf71f> in <module>
----> 1 c >= 10

TypeError: '>=' not supported between instances of 'list' and 'int'


# 2. for문과 if문을 혼용하여 가져와보자
>>> result = []
>>> for i in c:
>>>     if i >= 10:
>>>         result.append(i)
>>>     
>>> print(result)
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

# 3. 위 코드보다 단순하게 적어보자
>>> [i for i in c if i >= 10]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
  • R이나 파이썬 numpy의 array는 c[c>=10] 처럼 단순한 코드로 조건에 해당하는 값을 가지고 올 수 있으나, list는 이 방법으로 data를 가지고 올 수 없다.
  • if문을 사용하여야하며, 아직 익숙하지 않은 사람이라면 "# 2. 주석"대로 코드를 짜는 것이 쉬우며, 어느 정도 코드에 익숙해진 후에는 "# 3. 주석"의 코드 같이 짧은 코드로 짜도록 하자.

 

 

 

기타 리스트에서 자주 쓰이는 함수

# 1. append: list에 값 추가
>>> e = []
>>> for i in range(2, 10, 2):
>>>     e.append(i)
>>>     
>>> print(e)
[2, 4, 6, 8]

>>> e0 = [1,3,5]
>>> e0.append([2,4,5])
>>> print(e0)
[1, 3, 5, [2, 4, 5]]




# 2. extend: list에 다른 list의 원소들을 추가하기
>>> e.extend([1,3,5,7])
>>> print(e)
[2, 4, 6, 8, 1, 3, 5, 7]




# 3. sort: 정렬
>>> e.sort(reverse = True)
>>> print(e)
[8, 7, 6, 5, 4, 3, 2, 1]

>>> e.sort()
>>> print(e)
[1, 2, 3, 4, 5, 6, 7, 8]




# 4. insert: 삽입
>>> e.insert(2, 20)
>>> print(e)
[1, 2, 20, 3, 4, 5, 6, 7, 8]




# 5. pop: 뽑아내기
>>> e1 = e.pop(2)
>>> print(e1)
20
>>> print(e)
[1, 2, 3, 4, 5, 6, 7, 8]




# 6. remove: 가장 왼쪽에 있는 해당하는 값 제거
>>> f = [4,5,6] * 3
>>> f.remove(5)
>>> print(f)
[4, 6, 4, 5, 6, 4, 5, 6]




# 7. len: list 내 원소의 갯수 세기
>>> print(len(f))
8




# 8. count: list 내 특정 원소의 갯수 세기
>>> print(f.count(5))
2
  • list.append(value)는 list에 다른 값(list도 하나의 원소로써 추가 가능!)을 추가하는 함수다.
  • list.extend(list)는 list + list랑 같다
  • list.sort(reverse = False)는 자주 쓰이는 함수인데, reverse는 역순으로 정렬하느냐를 의미한다. 기본적으로 reverse = False로 지정돼있으며, 이는 오름차순(작은 순)이다.
  • 그냥 list의 순서를 거꾸로 하고 싶다면 list.reverse()를 쓰자
  • list.insert(위치, 값) 함수를 이용하면 내가 원하는 위치에 원하는 값을 넣을 수 있다.
  • list.pop(위치) 함수는 해당 위치에 있는 value를 아예 뽑아버린다!
  • list.remove(값) 함수는 가장 왼쪽에 있는 해당 값만 제거하므로 모두 제거하고 싶다면 for문이나 while문으로 반복실행하자
  • len(list) 함수는 list 내 원소의 수를 가지고 온다.
  • len(문자) 함수는 문자의 길이를 반환한다.
  • list.count(value)는 list 내 value의 개수를 가져오는 유용한 함수다.

 

 지금까지 list type에 대해 빠르게 훑어봤는데, 파이썬의 가장 기초가 되는 Data를 담는 type이다 보니 꽤 자주 쓰이는 type이다.

 위의 list 관련 함수들을 보다 보면, 분석가가 바라는 기능에 비해 조금씩 나사가 빠져있어, 원하는 결과를 내기 위해선 for문이나 while문을 섞어줘야 하는 경우가 꽤 있다.

 이 것이 본문에서 "list는 Data를 담는 그릇이지, 연산을 위한 Type은 아니다"라 한 이유이기도 한데, 이후에 학습할 array, DataFrame 등은 연산이나 데이터 정리에 훨씬 특화돼있기 때문에 연산이나 Indexing 등에서 훨씬 쉽고 우월한 성능을 낸다.

 이후 포스트에서 다룰 array와 DataFrame 등은 그 기능이 굉장히 다양하고, 이를 설명하려면 어지간한 전공서적만큼 설명이 필요하므로, 나머지 Type 포스팅에선 살짝 찍어만 먹어보고, 다른 카테고리인 Python-Pandas와 Python-Numpy에서 자세히 다뤄보자.

728x90
반응형
728x90
반응형

지금까지 R의 기본적인 데이터 타입인 스칼라, 벡터, 행렬, 배열, 데이터프레임에 대해 공부해보았다.

이번 포스트에서는 R에서 기본적으로 제공하는 마지막 데이터 타입인 List에 대해 공부해보도록 하자.

 

 

리스트(List)

: 리스트는 R에 있는 데이터 타입 중 가장 독특한 데이터 타입이라고 할 수 있는데, 말 그대로 모든 데이터 타입을 담을 수 있는 데이터 타입이 바로 리스트이다.

  • 리스트는 key, value 형태로 이루어져있다.
  • 리스트는 모든 데이터 구조를 포함하는 데이터 구조이다.
  • 여러 데이터 구조를 합하여 하나의 리스트를 만들 수 있다.
  • 다른 언어의 Hash table이나 Dictionary에 해당한다.
  • 서로 다른 변수 타입을 담을 수 있다.
  • 리스트는 배열(Array), 데이터프레임(Data Frame)과 달리 들어가는 데이터들의 길이가 서로 같지 않아도 담을 수 있다.
  • 리스트에 담긴 데이터마다 이름(key)을 부여할 수 있다.
  • list()
    : 리스트를 만드는 함수
# 데이터프레임, 행렬, 벡터가 들어간 리스트를 만들어보자.
vt1 = c("민철", "재성", "기훈", "현승", "현택", "윤기" ,"재빈", "현희", "미선", "선화")
vt2 = c(70, 60, 50, 80, 90, 80, 65, 75, 90, 80)
vt3 = c(80, 70, 85, 65, 55, 70, 75, 80, 65, 75)
vt4 = c(75, 80, 90, 75, 85, 75, 80, 85, 80, 85)

df = data.frame("name" = vt1, "math" = vt2, "english" = vt3, "science" = vt4)

mat = matrix(seq(1, 12), nrow = 4)

vt = c("A", "B", "C", "D")
List = list(data1 = df, data2 = mat, data3 = vt)
List
## $data1
##    name math english science
## 1  민철   70      80      75
## 2  재성   60      70      80
## 3  기훈   50      85      90
## 4  현승   80      65      75
## 5  현택   90      55      85
## 6  윤기   80      70      75
## 7  재빈   65      75      80
## 8  현희   75      80      85
## 9  미선   90      65      80
## 10 선화   80      75      85
## 
## $data2
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
## 
## $data3
## [1] "A" "B" "C" "D"
  • 리스트 생성 시, 정한 이름으로 각 데이터의 key 값이 생성된 것을 알 수 있다.

 

 

 

리스트의 indexing

  • 리스트의 특징은 리스트에 포함된 데이터들을 key라는 이름으로 불러올 수 있다는 것이다.
  • 리스트의 indexing 방식은 지금까지와 약간 다르므로, 표로 정리해보겠다.
문법 의미
list$key 리스트 list에서 키 값 key에 해당하는 데이터를 가지고 온다.
list[n] 리스트 list에서 n번째 데이터의 서브리스트를 가지고 온다.
list[[n]] 리스트 list에서 n번째 저장된 값을 가지고 온다.
List$data1
##    name math english science
## 1  민철   70      80      75
## 2  재성   60      70      80
## 3  기훈   50      85      90
## 4  현승   80      65      75
## 5  현택   90      55      85
## 6  윤기   80      70      75
## 7  재빈   65      75      80
## 8  현희   75      80      85
## 9  미선   90      65      80
## 10 선화   80      75      85
List[2]
## $data2
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
  • 위 표에서 설명한 서브리스트가 바로 위 형태이다.
  • list는 key와 value 2가지로 이루어져있으며, 위 List[2]의 결과를 보면, 이 역시 key와 value 2가지로 이루어진 list형임을 알 수 있다.
List[[2]]
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
  • [[n]]를 사용하면, 서브리스트가 아닌 그 데이터를 바로 가지고 온다.

 

 

리스트형에 대한 설명은 여기까지 하도록 하겠다.

설명이 매우 짧기 때문에 리스트형의 사용 용도가 그리 많지 않을 것으로 생각할 수 있는데, 길이가 다른 데이터 형을 담을 수 있다는 list형은 그 특징만으로도 사용처가 상당히 많다고 할 수 있다.

특히 R에 있는 lapply와 같은 리스트 형을 대상으로 한 함수나, 들어가는 데이터와 나오는 데이터의 길이가 불규칙한 경우, list형을 사용하면 쉽게 해결할 수 있다.

 

지금까지 R의 가장 기초가 되는 데이터 타입에 대해 공부해보았다.

데이터 타입은 R을 쓸 때, 기본 상식처럼 다룰 수 있어야하며, 데이터 타입을 잘 다루는 것이 R로 코드를 짤 때, 기초가 되는 부분이라고 할 수 있다.

다음 포스트에선 지금까지 공부한 타입과 그 판별, 변환 방법에 간략하게 정리를 해보도록 하겠다.

728x90
반응형

'R > Basic' 카테고리의 다른 글

R(기초) 패키지란?  (0) 2020.06.23
R(기초) 데이터 타입 판별과 타입 변환  (0) 2020.06.22
R(기초) 데이터프레임(DataFrame)(2부)  (0) 2020.06.22
R(기초) 데이터프레임(Data Frame)(1부)  (0) 2020.06.21
R(기초) 배열(Array)  (0) 2020.06.19

+ Recent posts