내가 정리하는 자료구조 02 Linked List

대표적인 데이터 구조: 링크드 리스트 (Linked List)

1. 링크드 리스트 (Linked List) 구조

  • 연결 리스트라고도 함
  • 배열은 순차적으로 연결된 공간에 데이터를 나열하는 데이터 구조
    • 그렇기 때문에 미리 연결된 공간을 예약을 해놓아야 한다는 것이 단점!
  • 링크드 리스트는 위와 같은 배열의 단점을 보완하고자 떨어진 곳에 존재하는 데이터를 화살표로 연결해서 관리하는 데이터 구조
  • 본래 C언어에서는 주요한 데이터 구조이지만, 파이썬은 리스트 타입이 링크드 리스트의 기능을 모두 지원
  • 링크드 리스트 기본 구조와 용어

    • 노드(Node): 데이터 저장 단위 (데이터값, 포인터) 로 구성
    • 포인터(pointer): 각 노드 안에서, 다음이나 이전의 노드와의 연결 정보를 가지고 있는 공간


2. 간단한 링크드 리스트 예

Node 구현

간단한 노드 1

1
2
3
4
class Node:
def __init__(self, data):
self.data = data
self.next = None

간단한 노드 2

1
2
3
4
class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next

Node

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Node:
def __init__(self, data):
self.__data=data
self.__next=None

@property
def data(self):
return self.__data

@data.setter
def data(self, data):
self.__data=data


@property
def next(self):
return self.__next

@next.setter
def next(self, n):
self.__next=n

Node와 Node 연결하기 (포인터 활용)


1
2
3
4
5
6
7
8
node1 = Node(1)
node2 = Node(2)
print(node1.data)
node1.data=2
print(node1.data)

node1.next = node2
print(node1.next.data)

결과

1
2
3
1
2
2

3. 링크드 리스트의 장단점 (전통적인 C언어에서의 배열과 링크드 리스트)

  • 장점
    • 미리 데이터 공간을 미리 할당하지 않아도 됨
      • 배열은 미리 데이터 공간을 할당 해야 함
  • 단점
    • 연결을 위한 별도 데이터 공간이 필요하므로, 저장공간 효율이 높지 않음
    • 연결 정보를 찾는 시간이 필요하므로 접근 속도가 느림 그에 반해 배열은 인덱싱을 통해 빠르게 접근할 수 있음
    • 중간 데이터 삭제시, 앞뒤 데이터의 연결을 재구성해야 하는 부가적인 작업 필요

4. 링크드 리스트의 복잡한 기능1 (링크드 리스트 데이터 사이에 데이터를 추가)

  • 링크드 리스트는 유지 관리에 부가적인 구현이 필요함


(출처: wikipedia, https://en.wikipedia.org/wiki/Linked_list)

링크드 리스트의 사이에 데이터를 추가하기


1
2
3
4
5
6
7
8
9
10
class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next

def add(data):
node = head
while node.next:
node = node.next
node.next = Node(data)

1
2
3
4
node1 = Node(1)
head = node1
for index in range(2, 10):
add(index)

링크드 리스트 데이터 출력하기(검색하기)

1
2
3
4
5
node = head
while node.next:
print(node.data)
node = node.next
print (node.data)
결과
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9

  • node3이 들어갈 자리를 아래와 같이 1의 데이터값을 갖는 노드 다음에 위치시키려면 1의 값을 갖는 노드의 next값을 먼저 저장해준뒤, 다음에 node3을 연결해준다. 그리고 다시 node3의 next가 이전 1의 값을 갖는 node의 next를 가리키게 하면된다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    node3 = Node(1.5)

    node = head
    search = True
    while search:
    if node.data == 1:
    search = False
    else:
    node = node.next

    node_next = node.next
    node.next = node3
    node3.next = node_next

  • 이제 원하는대로 node가 삽입 되었는지 살펴보자.

1
2
3
4
5
node = head
while node.next:
print(node.data)
node = node.next
print (node.data)
결과
1
2
3
4
5
6
7
8
9
10
1
1.5
2
3
4
5
6
7
8
9

Pseudo Code for Single Linked List

  • 위에서 언급한 기능들을 포함한 Single linked List를 객체로 만들어 본다.

    1. 먼저, Single linked List에 필요한 기능 중 하나인 next를 찾으려면 시작점을 정해주어야 할 것이다. 그러므로 head와 리스트의 전체 사이즈를 나타내는 n_size를 만들어준다.
    1. 리스트를 추가해주는 add와 해당 데이터 값을 갖고있는 노드의 위치와 데이터값을 출력해주는 search를 만든다. add를 만들 때 주의할 점은head가 새롭게 추가되는 데이터가 되도록만들어 준다는 것을 생각해주어야 한다. next로 연결해주는 순서를 통해 만들어준다. search를 만들때 주의점은 while문을 돌면서 head 부터 시작하여 차례대로 찾는값과 비교해 주는데 찾는값이 해당 Linked list에 꼭 있다는 보장이 없기 때문에 data.next = None (마지막 노드)인 경우에는 cur.data가 없어 error를 발생시키게 된다. 그러므로 우선 cur의 데이터가 존재하는지 부터 생각하자. 또한, Node 자체를 반환해주는 식으로 작성해야 할 것이다. Linked list는 노드의 연결체이기 때문이다.
    1. delete함수는 python의 garbage collection을 통해 head였던 node의 연결을 끊어 줌으로써 구현할 수 있다.
    1. traverse함수는 제너레이터를 사용하여 전체적인 노드값을 보여주는 제너레이터는 제너레이터 객체에서 next 메서드를 호출할 때마다 함수 안의 yield까지 코드를 실행하며 yield에서 값을 발생시킨다.(generate) yield를 사용하면 값을 함수 바깥으로 전달하면서 코드 실행을 함수 바깥에 양보하게된다. 따라서 yield는 현재 함수를 잠시 중단하고 함수 바깥의 코드가 실행되도록 만든다.

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
class Node:
def __init__(self, data):
self.__data=data
self.__next=None

@property
def data(self):
return self.__data

@data.setter
def data(self, data):
self.__data=data


@property
def next(self):
return self.__next

@next.setter
def next(self, n):
self.__next=n

class Single_Linked_List:

def __init__(self):
self.head=None
self.n_size=0

def empty(self):
if self.n_size==0:
return True
else :
return False

def size(self):
return self.n_size

def add(self, data):
node=Node(data)
if self.head==None:
self.head=node
self.n_size+=1
else:
cur=self.head
while cur:
if cur.next == None:
cur.next=node
self.n_size += 1
cur=node.next
else:
cur = cur.next

def add_after(self, data, target):
node=Node(data)
cur=self.head
while cur:
if cur.data == target:
cur_next=cur.next
cur.next=node
node.next=cur_next
break
else:
cur=cur.next


def search(self, data):
"""
이 함수는 리스트의 search 명령과 같이 동일한 값을 갖는 처음 만나는 노드를 반환한다.
"""
cur=self.head
while cur:
if cur.data == data:
return cur
else:
cur=cur.next

def delete(self, data):
"""
이 함수는 python의 garbage collection의 개념을 통해 연결을 끊어 제거해주는 방식으로 구현하였다.
"""
cur = self.head
while cur:
if cur.data == data:
previous.next =cur.next
break
previous = cur
cur = cur.next
self.n_size -= 1

def traverse(self):
cur=self.head
while cur:
yield cur
cur=cur.next


1
2
3
4
5
6
def show_list(slist):
print('data size : {}'.format(slist.size()))
g=slist.traverse()
for node in g:
print(node.data, end= ' ')
print()

리스트에 삽입 및 데이터 확인


1
2
3
4
5
6
7
8
9
10
11
slist=Single_Linked_List()

print('데이터 삽입')
slist.add(3)
slist.add(1)
slist.add(5)
slist.add(2)
slist.add(7)
slist.add(8)
slist.add(3)
show_list(slist)

결과

1
2
3
데이터 삽입
data size : 7
3 1 5 2 7 8 3

리스트 중간에 삽입


1
2
slist.add_after(7, 5)
show_list(slist)

결과

1
2
data size : 7
3 1 5 7 2 7 8 3


1
2
3
4
5
6
7
8
9
print('데이터 탐색')
target=7
res=slist.search(target)
if res:
print('데이터 {} 검색 성공'.format(res.data))
else:
print('데이터 {} 탐색 실패'.format(target))
res=None
print()

결과

1
2
데이터 탐색
데이터 7 검색 성공

delete


1
2
3
4
5
print('데이터 삭제')
slist.delete(5)
slist.delete(7)
slist.delete(8)
show_list(slist)

결과

1
2
3
데이터 삭제
data size : 4
3 1 2 7 3

7. 다양한 링크드 리스트 구조

  • 더블 링크드 리스트(Doubly linked list) 기본 구조
  • 위에서 언급한 것과 같이 양방향에서 모두 탐색이 가능하다는 점을 주의하자.
    • 양방향을 사용하기 위해선 위에서 정의했던 노드의 방향을 추가하여 재정의해주어야한다.

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
class Node:
def __init__(self,data=None):
self.__data = data
self. __next = None
self.__before = None
# 소멸자 : 객체가 메모리에서 사라질 때 반드시 한번 호출하는 것을 보장
def __del__(self):
print('{} is deleted'.format(self.__data))

@property
def data(self):
return self.__data

@data.setter
def data(self, data):
self.__data = data

@property
def next(self):
return self.__next

@next.setter
def next(self, next):
self.__next = next

@property
def before(self):
return self.__before

@before.setter
def before(self, before):
self.__before = before

Pseudo Code for Single Linked List

  • 가장 먼저 single linked list와 다르게 head만 존재하는 것이 아니라 tail도 존재한다는 것을 유의하자.

  • 필요한 기능을 나열해보자. 대략적으로 나누어서 생각해보면 다음과 같은 기능들이 필요할 것이다.

    • size
    • empty
    • add
      • head after
      • tail before
      • mid
    • search
      • head -> tail
      • tail -> head
    • delete
      • head
      • tail
      • mid
  • insert_after, insert_before는 if문의 순서를 바꾸어 주어 링크드리스트내에 노드가 1개짜리인 경우에는 각각 add_firstadd_last를 하는 것과 동일하므로 함수로 계산하는 것으로 대체해주었다.


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
class DoubleLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.d_size = 0

def empty(self):
if self.d_size==0:
return True
else:
return False

def size(self):
return self.d_size


def add_first(self, data):
if self.empty():
new=Node(data)
self.head=new
self.tail=new
self.d_size+=1
else:
new=Node(data)
new.next=self.head
self.head.before=new
self.head=new
self.d_size+=1


def add_last(self, data):
if self.empty():
new=Node(data)
self.head=new
self.tail=new
self.d_size+=1
else:
new=Node(data)
self.tail.next=new
new.before=self.tail
self.tail=new
self.d_size+=1


def insert_after(self, data, node):
if node == self.tail:
self.add_last(data)
elif node == self.head:
new=Node(data)
new.next=self.head.next
new.before=self.head
self.head.next.before=new
self.head.next=new
self.d_size+=1
else:
new=Node(data)
new.next=node.next
new.before=node
node.next.before=new
node.next=new
self.d_size+=1

def insert_before(self, data, node):
if node == self.head:
print("this")
self.add_first(data)
elif node == self.tail:
print("is")
new=Node(data)
new.next=self.tail
new.before=self.tail.before
self.tail.before.next=new
self.tail.before=new
self.d_size+=1
else:
print("shit")
new=Node(data)
new.next=node
new.before=node.before
node.before.next=new
node.before=new
self.d_size+=1

def search_forward(self, data):
cur=self.head
while cur:
if cur.data==data:
return cur
else:
cur=cur.next
if cur == None:
print("리스트 안에 찾는 데이터가 존재하지 않습니다.")

def search_backward(self, data):
cur=self.tail
while cur:
if cur.data == data:
return cur
else:
cur=cur.before
if cur == None:
print("리스트 안에 찾는 데이터가 존재하지 않습니다.")

def delete_first(self):
new_head=self.head.next
self.head.next=None
self.head=new_head
new_head.before=None
self.d_size-=1

def delete_last(self):
new_tail=self.tail.before
self.tail.before=None
self.tail=new_tail
self.tail.next=None
self.d_size-=1


def delete_node(self, node):
if node == self.head:
self.delete_first()
elif node == self.tail:
self.delete_last()
else:
node.before.next=node.next
node.next.before=node.before

def traverse(self, start=True):
"""
start=True --> from head
start=False --> from tail
"""
if start:
cur=self.head
while cur:
yield cur
cur=cur.next
else:
cur=self.tail
while cur:
yield cur
cur=cur.before


1
2
3
4
5
6
def show_list(dlist, start=True):
print('data size : {}'.format(dlist.size()))
g=dlist.traverse(start)
for node in g:
print(node.data, end=' ')
print()

make a double linked list


1
dlist=DoubleLinkedList()

insert 1 - add_first


1
2
3
4
5
6
print('데이터 삽입 -add_first')
dlist.add_first(1)
dlist.add_first(2)
dlist.add_first(3)
dlist.add_first(5)
show_list(dlist, start=True)

결과

1
2
3
데이터 삽입 -add_first
data size : 4
5 3 2 1

insert 2 - add_last


1
2
3
4
5
6
print('데이터 삽입 -add_last')
dlist.add_last(1)
dlist.add_last(2)
dlist.add_last(3)
dlist.add_last(5)
show_list(dlist, start=True)

결과

1
2
3
데이터 삽입 -add_last
data size : 8
5 3 2 1 1 2 3 5

insert 3 - insert_after


1
2
3
print('데이터 삽입 - insert_after')
dlist.insert_after(4, dlist.search_forward(5))
show_list(dlist, start=True)

결과

1
2
3
데이터 삽입 - insert_after
data size : 9
5 4 3 2 1 1 2 3 5

insert 4 - insert_before


1
2
3
print('데이터 삽입 - insert_before')
dlist.insert_before(4, node=dlist.search_forward(5))
show_list(dlist, start=True)

결과

1
2
3
4
데이터 삽입 - insert_before
this
data size : 10
4 5 4 3 2 1 1 2 3 5

search


1
2
3
4
5
6
7
8
9
print('데이터 탐색')
target=2
#res=dlist.search_forward(target)
res=dlist.search_backward(target)
if res:
print('데이터 {} 탐색 성공'.format(res.data))
else:
print('데이터 {} 탐색 실패'.format(target))
res=None

결과

1
2
데이터 탐색
데이터 2 탐색 성공

delete_first


1
2
3
dlist.delete_first()
dlist.delete_first()
show_list(dlist, start=True)

결과

1
2
3
4
4 is deleted
5 is deleted
data size : 8
4 3 2 1 1 2 3 5

delete_last


1
2
3
dlist.delete_last()
dlist.delete_last()
show_list(dlist, start=True)

결과

1
2
3
4
5 is deleted
3 is deleted
data size : 6
4 3 2 1 1 2

delete_node


1
2
dlist.delete_node(dlist.search_backward(1))
show_list(dlist, start=True)

결과

1
2
3
1 is deleted
data size : 6
4 3 2 1 2

  • 위의 테스트와 동일한 결과를 출력하나 head와 tail을 Node로 만들어 head와 tail에 관해 좀더 직관적으로 확인할 수 있고, Node 추가시 조금의 이점이 더 있게끔 구현해본 또 다른 코드이다.

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
class DoubleLinkedList:
def __init__(self):
self.head = Node()
self.tail = Node()
self.head.next = self.tail
self.tail.before = self.head
self.d_size = 0

def empty(self):
if self.d_size==0:
return True
else :
return False

def size(self):
return self.d_size

def add_first(self, data):
#새 노드를 생성
new_node = Node(data)

new_node.next = self.head.next
new_node.before = self.head
#위의 두가지는 순서가 바뀌어도 됨!
self.head.next.before = new_node
self.head.next = new_node

self.d_size+=1


def add_last(self, data):
new_node = Node(data)

new_node.next = self.tail
new_node.before = self.tail.before

self.tail.before.next = new_node
self.tail.before = new_node

self.d_size+=1

def insert_after(self, data, node):
new_node = Node(data)

new_node.next = node.next
new_node.before = node
#new_node.before = node.next.before
node.next.before = new_node
node.next = new_node

self.d_size+=1

def insert_before(self, data, node):
new_node = Node(data)

new_node.next = node
new_node.before = node.before
node.before.next = new_node
node.before = new_node

self.d_size+=1


def search_forward(self, data):
current = self.head.next
while(current is not self.tail):
if(current.data == data):
return current
else:
current = current.next
return None

def search_backward(self, data):
current = self.tail.before
while(current is not self.head): # 주소값을 비교하기 때문에 !=이 아닌 is not으로 하는 것이 더 좋음!!
if(current.data == data):
return current
else:
current = current.before
return None

def delete_first(self):
if self.empty():
return
self.head.next = self.head.next.next
self.head.next.before = self.head

self.d_size-=1

def delete_last(self):
if self.empty():
return
self.tail.before=self.tail.before.before
self.tail.before.next=self.tail

self.d_size-=1

def delete_node(self, node):
node.before.next=node.next #reference count가 0이되어 사라짐!
node.next.before=node.before

self.d_size-=1

def traverse(self, start=True):
"""
start=True --> from head
start=False --> from tail
"""
if start:
cur=self.head
while cur is not self.tail:
yield cur
cur=cur.next
else:
cur=self.tail.before
while cur is not self.head:
yield cur
cur=cur.before

위의 클래스를 사용하여 Python의 리스트를 구현해보았다.


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
from double_linked_list import DoubleLinkedList

class PseudoList(DoubleLinkedList):
#pos는 파이썬 리스트의 인덱스와 비슷하게
#데이터의 위치를 나타냄.
#인덱스처럼 0이 첫번째 위치를 의미
def __init__(self, *args):
super().__init__()
for elem in args:
self.add_last(elem)

#전역함수 len(list)을 호출할 때 이 함수가 호출
def __len__(self):
return self.size()

#파이썬 리스트의 append는 맨 뒤에 데이터를 추가
#더블 링크드 리스트에 있는 add_last 함수를 사용
def append(self, data): #래핑 함수
self.add_last(data)


#인자로 pos를 받으면 pos에 위치한 노드를 반환한다.
def __find_position(self, pos):
if pos >=self.size():
raise IndexError('list index out of range')
cur = self.head.next
for _ in range(pos):
cur = cur.next
return cur

#pos에 위치한 노드를 구한 뒤 --> __find_position()
#그 노드의 앞에 데이터를 삽입 --> insert_before()
def insert(self, pos, data):
node = self.__find_position(pos)
self.insert_before(data, node)

#리스트에 있는 data의 개수를 카운트
#리스트를 순회하면서 데이터가 있으면 cnt 변수를 1씩 증가시킴
def count(self, data):
cnt = 0
cur = self.head.next
while cur is not self.tail:
if cur.data == data:
cnt += 1
cur = cur.next
return cnt

#인자 data가 위치한 인덱스를(여기에서는 pos) 반환한다
#start는 데이터를 찾기 시작하는 위치
def index(self, data, start=0):
cur = self.__find_position(start)
index = start

while cur:
if cur.data == data:
return index
cur = cur.next
index += 1

raise ValueError('{} is not in the list'.format(data))

#print(li[3]) 처럼 [] 연산자를 통해 값을 가져올 때 내부에서 호출
#index는 pos를 의미
#index에 위치한 노드의 데이터를 반환
def __getitem__(self, index):#연산자 오버로딩
node = self.__find_position(index)
return node.data

#li[3]=10 처럼 [] 연산자로 값을 대입할 때 내부에서 호출
#index는 pos를 의미
#index에 위치한 노드의 값을 data로 바꿈
def __setitem__(self, index, data):#연산자 오버로딩
node = self.__find_position(index)
node.data = data

#pos에 있는 데이터를 삭제하면서 반환
#파이썬 리스트처럼 인자를 주지 않으면
#리스트의 맨 마지막 데이터를 삭제하면서 반환
def pop(self, pos=None):
#인자 pos가 있는 경우
if pos:
node = self.__find_position(pos)
#pos가 비어 있는 경우
else:
node = self.tail.before
#delete_node 함수를 이용해 노드 삭제
cur = node
self.delete_node(node)
return cur.data

#리스트에 있는 데이터를 삭제
#만약 같은 데이터가 여러개라면
#리스트에서 위치상 첫번째 데이터가 삭제된다
#반환은 하지 않는다
def remove(self, data):
#delete_node와 search_forward 함수 이용
self.delete_node(self.search_forward(data))

def __str__(self):
string = '['
cur = self.head.next
while cur is not self.tail:
string+=str(cur.data)
if cur.next is not self.tail:
string+=', '
cur= cur.next

string+=']'
return string

객체 생성


1
2
3
4
5
6
7
8
initial = [1, 2, 3, 4]
#pseudo_list
li = PseudoList(*initial)
#python list
py_li = initial

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
pseudo list : [1, 2, 3, 4]
python list : [1, 2, 3, 4]

append


1
2
3
4
5
6
7
8
9
10
11
12
13
#pseudo_list
li.append(2)
li.append(1)
li.append(2)
li.append(7)
#python_list
py_li.append(2)
py_li.append(1)
py_li.append(2)
py_li.append(7)

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
pseudo list : [1, 2, 3, 4, 2, 1, 2, 7]
python list : [1, 2, 3, 4, 2, 1, 2, 7]

count


1
2
3
target = 2
print('count of {} : {} in pseudo_list'.format(target, li.count(target)))
print('count of {} : {} in python_list'.format(target, py_li.count(target)))

결과

1
2
count of 2 : 3 in pseudo_list
count of 2 : 3 in python_list

pop


1
2
3
4
5
6
7
#pseudo_list
li.pop(2)
#python_list
py_li.pop(2)

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
3
4
data of 7 is deleted
data of 2 is deleted
pseudo list : [1, 2, 3, 4, 2, 1]
python list : [1, 2, 3, 4, 2, 1]

pop(index)


1
2
3
4
5
6
7
#pseudo_list
li.pop(2)
#python_list
py_li.pop(2)

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
3
data of 3 is deleted
pseudo list : [1, 2, 4, 2, 1]
python list : [1, 2, 4, 2, 1]

insert


1
2
3
4
5
6
7
#pseudo_list
li.insert(3, 9)
#python_list
py_li.insert(3, 9)

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
pseudo list : [1, 2, 4, 9, 2, 1]
python list : [1, 2, 4, 9, 2, 1]

index


1
2
3
4
target = 9

print("index of {} : {} in pseudo_list".format(target, li.index(target)))
print("index of {} : {} in python_list".format(target, py_li.index(target)))

결과

1
2
index of 9 : 3 in pseudo_list
index of 9 : 3 in python_list

indexing


1
2
3
4
5
6
7
#pseudo_list
li[3]=7
#python_list
py_li[3]=7

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
pseudo list : [1, 2, 4, 7, 2, 1]
python list : [1, 2, 4, 7, 2, 1]

remove


1
2
3
4
5
6
7
#pseudo_list
li.remove(9)
#python_list
py_li.remove(9)

print("pseudo list : "+ str(li))
print("python list : " + str(py_li))

결과

1
2
3
data of 9 is deleted
pseudo list : [1, 2, 4, 2, 1]
python list : [1, 2, 4, 2, 1]