Sister Nosilv story

[+복습(2)] 3. 프로그래밍과 데이터 中 값 관련 함수 & 메소드

by 노실언니

[복습위치]

프로그래밍과 데이터-Python programming and data 中 관련 함수

[복습 목표] : # 여러 요소 중 특정 값을 짚는 방식 # Mutable/Immutable의 값 수정 방식에 대한 세부적 접근

     + 관련 함수/메소드/연산자 익히기

 

[배경지식 & 이전복습]

- 자료형분류 : ① 독방 VS 여러명가능 ②값 변경시 변수→객체 도킹스타일

  Limited number of items that can be in this type of object(1factor VS Nfactor)

   N factors type[Str List Tuple Dict Set] : 특정 요소를 짚을 수 있으려면, (요소↔유일한 지표)가 필요.

   유일한 지표 : Index(Str List Tuple), Key(Dict), 값 그 자체(Set) → 이를 이용하여 일부 참조/수정이 이뤄짐

  [changing whole value VS only some part of value] + [Mutable VS Immutable]

  └ Changing Whole value : [New Object in New memory address]도킹 ← variable

  └ Changing some factors of 'N factors' type's value

    1) Mutable : [New Object in New memory address]도킹 ← 前/後 다른 factor들과 도킹

          ∴ variable의 도킹상태 'intact'

    2) Immutable : Mutable의 방식 불가능

          ∴ 함수/메소드/연산자를 통해 whole change방식으로 전환하여 값을 수정해야함


 

[All type] 값 & 주소 관련

ID 알려줘 → return ID :

 └ id(    )

* ID : 변수/함수가 가리키는 객체가 사는 주소 or 값이 저장된 주소와 1:1대응하는 ID

↓ id( 값 or 변수 ) ↓

a = '1'
print(id('1'))          # ■ 1239846394608
print(id(1))            # ◆ 1239842122032
print(id(a))            # ■ 1239846394608
# >>> type 이 다르면, 명백하게 다른 값

print(id(int(a)))       # ◆ 1239842122032
# >>> 둘이 같은 값을 불러내는 경우,
# >>> 다른 두 메모리공간에 같은 값의 객체를 만드는 것이 아니라
# >>> <한 객체를 두 번 사용> 하도록 하여 메모리사용을 최적화한다 <가설>

print(id(2))            # ▲ 1239842122064
print(id(int(a)+1))     # ▲ 1239842122064
print(id('1'))          # ■ 1239846394608
# >>> <가설:같은값이용→같은객체(주소)여러번 사용> 재확인
# + run 할 때마다, id 가 변함 ∵ run 끝나면 모두 삭제, re:run = new:run

↓ id( 함수 or 함수() ) ↓

def return_first():
    return '1'


print(return_first)        # <function return_first at 0x00000120AC9BD160>
print(id(return_first))    # ▼ 1239846474080
print(return_first is id(return_first)) # False
# >>> [WHY?] return_first at 0x00000120AC9BD160 ≠ [ID] 1239846474080

print(return_first())      # 1 : 해당 함수가 return '1'이므로
print(id(return_first()))  # ■ 1239846394608
print(id('1'))             # ■ 1239846394608
a = [3, 2, '1']
print(id(a[2]))            # ■ 1239846394608
# >>> id(함수 그 자체) ≠ id(함수가 리턴한 객체)
# + 계속 '1'의 주소가 같다 : <가설:같은값이용 → 같은객체(주소)여러번 사용> 재확인

* 의문1. : 함수명 is id(함수명) = False 의 의미

* 의문2. : 함수명 at [주소] 와 [id(함수명)]이 다른 것에 대한 의미


둘의 메모리주소 같아? → return T/F :

 └ ■ is ▲

* 주소 : 메모리공간 中 변수/함수가 '가리키는' 객체가 사는 곳의 주소 or 값이 저장된 곳의 주소

- run 할 때마다, 주소가 변한다 ∵ run 끝나면 모두 삭제, re:run = new:run

- 같은 값 호출 → 특정 주소에 존재하는 한 객체를 여러번 호출하여 메모리최적화 [usually]


둘의 값이 같아? → return T/F :

 └ ■ == ▲

- 같은 값 호출 → 특정 주소에 존재하는 한 객체를 여러번 호출하여 메모리최적화한다는 규칙 [usually]

 

[의문3.] : 위의 규칙이 맞다면 mutable type(가변형)변수를 deepcopy 후 일부 변경하는 경우, 메모리주소는 어떻게 되나?

     다른 주소에 같은 값의 다른 객체가 존재하게 되나?

a = [3, 2, '1']
print(id(a[2]))             # ■ 1239846394608 : '1'

import copy
b = copy.deepcopy(a)
print(id(b[2]))             # ■ 1239846394608 : '1'
print(a is b)               # False
print(a[2] is b[2])         # True ■
print(a[2] == b[2])         # True '1'

c = a
print(a is c)               # True
# >>> a is c but, a is not b

b[2] = 1
print(id('1'))              # ■ 1239846394608 : '1'
print(id(a[2]))             # ■ 1239846394608 : '1'
print(id(b[2]))             # ◆ 1239842122032 : 1
print(a[2] is b[2])         # False : ■ '1'의 주소 ≠ ◆ 1의 주소
print(a[2] == b[2])         # False : '1' ≠  1

[의문3. 해결]

1. mutable type / b = a : id(a) == id(b) & id(a[0]) == id(b[0])

   + b의 일부 값 변경 → a도 같이 변경 [dependent] : id(a) == id(b) & id(a[0]) == id(b[0])

2. mutable type / b = copy.deepcopy(a) : id(a) != id(b) & id(a[0]) == id(b[0])

   + b의 일부 값 변경 → a는 불변 [independent] : id(a) != id(b) & id(a[0]) != id(b[0])

결론 : mutable type object를 담은 변수를 다른 변수에다 deepcopy하면, 두 변수가 가리키는 시작점은 다르다 ( a = b 인 경우는 같음 )

   시작점은 다르지만, 두 변수에 담긴 요소값들은 copy되어 똑같으므로

   [같은 값 호출 → 특정 주소에 존재하는 한 객체를 여러번 호출]하려는 메모리최적화 규칙에 따라서, 시작점 이후로 가리키는 객체&메모리 주소는 동일하다

   그 상태로, 두 변수 중 한 변수의 일부 값이 변경되면 independent하게 작동하여 한 변수의 값(+주소)만 달라진다.

 

[+ (재)의문3.] : 이걸 저번 복습(1)때, 그렸던 방식으로 표현이 가능한가

  → No, 너무 슬프다. copy와 값변경은 내가 그린 그림으로 표현이 안 된다. 메모리최적화 규칙때문에...!!!

   사용자입장에서는 감사 & 배우는 입장에선 슬프고 화가 난다. 어떻게 하신거에요 ㅂㄷㅂㄷㅜㅜㅜㅜㅜㅜㅜㅜㅠㅠㅠㅠ

 

[N factors type]

N factors type : str list tuple dict set

 

Status파악관련

요소 몇 개야? → return (int) :

 └ len (    )

a = "Hi !"      # str
print(len(a))   # 4

b = [1, 2, 3]   # list
print(len(b))   # 3

c = {1: 1, 2: 2, 3: 3}      # dict
print(len(c))               # 3 → (Key:Value) * 3 = 3 pair
# len(Dict) : 쌍 단위로 셈

d = {1, 1, 1, 1, 1}         # set
print(len(d))               # 1
# set : 중복불가 → 요소자체가 식별키(≒index or key)

e = ([1, 2], 3, 4)          # type(type)
print(len(e))               # 3
print(type(e))              # <class 'tuple'>
print(len(e[0]))            # 2
print(type(e[0]))           # <class 'list'>
# ≒ 안은/안긴문장같은? 합성함수같은? 사이
#   → e[0] = tuple type의 1요소이자, 2요소를 가진 list type

[Remark] len (1 factor type) → Error

int_a = 10000000  # int
print(len(int_a)) # TypeError: object of type 'int' has no len()

이 값 존재해? → return T/F :

 └  값  in    

list_a = [1, '2', '', ' ', False]
print(1 in list_a)          # True

tuple_b = tuple(list_a)
print(2 in tuple_b)           # False : '2' ≠ 2
print('' in tuple_b)          # True
print(None in tuple_b)        # False : '' ≠ None & False ≠ None
print(bool('') in tuple_b)    # True  : bool('') = False
print(bool(None) in tuple_b)  # True  : bool(None) = False
print(' ' in tuple_b)         # True

dict_c = {"one": 1,
          "two": 2}
print("one" in dict_c)        # True
print(1 in dict_c)            # False : 'in' check only 'Key'
print('two' in dict_c)        # True
print(2 in dict_c)            # False : 'in' check only 'Key'

set_d = {1, 2, 3}
print(4 in set_d)             # False

str_e = "Hi! Hello."
print('!' in str_e)           # True
print(' ' in str_e)           # True  : 띄어쓰기
print('"' in str_e)           # False : ""는 str type을 나타내는 표식일 뿐

 

[Remark] Dict → 'Key'값만 사용 됨 : 다른 함수에서도 'Key'만 사용되는 걸 종종 봄

     + Dict의 value 중에서 존재확인 하고 싶다면? : 값 in dict_name.values()

dict_c = {"one": 1,
          "two": 2}
print("one" in dict_c)        # True
print(1 in dict_c)            # False : 'in' check only 'Key'
print(1 in dict_c.values())   # True

이 값 어디에 있어? → return int(에) :

 └    .index( )

 └    .find( )

 

.index : int형 index를 return하므로, string, list, tuple만 사용가능

    → dict는 key, set는 요소자체가 유일한 지표 ≠ 정수형 index

.index : 묻는 값이 존재하지 않는 경우, ValueError

.find : int형 index를 return하지만, string만 사용가능

.find : 묻는 값이 존재하지 않는 경우에도, -1

 

str_a = "123456"
list_b = ['1', 2, 3]
tuple_c = tuple(list_b)
dict_d = {'one': 1,
          'two': 2}
set_e = {'1', 2, 3}

print(str_a.index('1'))     # 0 : str_a[0] = '1'
print(str_a.index(1))       # TypeError: must be str, not int
print(list_b.index(3))      # 2 : list_b[2] = 3
print(list_b.index(1))      # ValueError: 1 is not in list
print(tuple_c.index('1'))   # 0 : tuple_c[0] = '1'
print(tuple_c.index(1))     # ValueError: tuple.index(x): x not in tuple
print(dict_d.index('1'))    # AttributeError: 'dict' object has no attribute 'index'
print(set_e.index('1'))     # AttributeError: 'set' object has no attribute 'index'

[Remark] 값이 존재하지 않는 경우 → ValueError : '값 in 덩어리'로 先 check 必

 

[의문 1.] : 先check 하지않고, 값이 존재하지 않을 때 Err 안 나게 할 수 있을까?

  → △, Only 'String' type.

    └    .find( )

      → If the value exist, return its index.

      → If the value doesn't exist, return -1. not error!

str_a = "1234566"
list_b = ['1', 2, 3]
tuple_c = tuple(list_b)
dict_d = {'one': 1,
          'two': 2}
set_e = {'1', 2, 3}

print(str_a.find(1))         # TypeError: must be str, not int

print(str_a.find('1'))       # 0 : str_a[0] = '1'
print(str_a.find('6'))       # 5 : str_a[5] = '6' → can find more ahead one only
print(str_a.find('7'))       # -1 : There is no '7' in '123456'

print(str_a.find('12345'))   # 0 : ??????????????? → if not exist, return -1
print(str_a.index('12345'))  # 0 : ??????????????? → if not exist, ValueError
print(str_a.find('67'))      # -1 : There is no '67' in '123456'

print(list_b.find(1))        # AttributeError: 'list' object has no attribute 'find'
print(tuple_c.find(1))       # AttributeError: 'tuple' object has no attribute 'find'
print(set_e.find(1))         # AttributeError: 'set' object has no attribute 'find'

[Remark] '여러값'이고 존재하는 경우 → return 첫번째 index

[Remark] 'abcabc'.index('a')처럼 값이 중복되는 경우 → return 첫번째 index


이 값 몇 개 있어? → return int(개) :

 └    .count( )

  * string, list, tuple만 사용가능 → dict는 key/value분리, set는 원래 중복불가능이라 객체가 count 메소드를 가지고 있지 않음

str_a = "122333"
tuple_b = (1, 2, 2, 3)
list_c = list(tuple_b)
dict_d = {'A': 1,
          'B': 2,
          'C': 1}
set_e = {1, 2, 2, 3}

print(str_a.count(2))       # TypeError: must be str, not int
print(str_a.count('2'))     # 2
print(str_a.count("233"))   # 1 : 여러개여도 괜찮
print(tuple_b.count(2))     # 2
print(list_c.count(2))      # 2
print(list_c.count(4))      # 0 : 값이 없어도 error 안 나고, 0 return
print(dict_d.count('A'))           # AttributeError: 'dict' object has no attribute 'count'
print(dict_d.keys().count('A'))    # AttributeError: 'dict_keys' object has no attribute 'count'
print(list(dict_d.keys()).count('A'))    # 1 : dict.keys/values()객체도 string, list, tuple로 변환하면 OK
print(set_e.count(2))              # AttributeError: 'set' object has no attribute 'count'

[Remark] : 값이 없어도 NO Error

[Remark] : str, list, tuple 객체만 count 메소드를 가지고 있으므로, 형변환을 이용해보자

 

호출 관련

모든 값 불러와:

 └ New Variable Name = 기존 object

  * 참조복사형태 : string, tuple [Immutable]은 참조복사든 값복사든 불변형이라, 변경하면 Error

  * Mutable은 이렇게하면 값이 같이 바뀔 수 있다.

 └ import copy

  copy.deepcopy(기존 object)

  * 값복사

 └ [:] slicing을 이용한 값복사


이 '자리'의 값만 불러와:

 └ [Str List Tup Dict] 값 하나 : object[ index or key]

  * 자리 개념이 있는 [string, list, tuple, dict]만 사용가능 = set 는 위치개념이 없음

  * 자리가 index인 경우 [string, list, tuple] → indexing이라고도 함

 └ [Dict] 값 하나 : dict object.get( key, (없는 key일 경우, 리턴할 값))

  * Dict만 가능 & 오류없음

  * Dict는 mutable이지만, dict.get(key)를 이용해서는 일부 값 변경 불가

 └ [Str List Tup] 여러 값 Slicing : object[ start index : end index+1 : 순/역순 여부]

  * 자리, 범위 개념이 있는 [string, list, tuple]만 사용가능 = dict는 key개념만 있음

* 마지막 인덱스의 +1 임에 주의

  * 역순 : -1 역순으로 복사할 때, 시작점/도착점도 역순이다. 주의하자

 

str_a = "1234"
tuple_b = (1, 2, 3, 4)
list_c = list(tuple_b)
dict_d = {'A': 1,
          'B': 2,
          'C': 3,
          'D': 4}
set_e = {1, 2, 3, 4}

print(str_a[0])     # 1
print(str_a[5])     # IndexError: string index out of range
print(tuple_b[1])   # 2
print(list_c[2])    # 3
print(dict_d['D'])  # 4
print(dict_d[3])    # KeyError: 3

print(str_a.get(0))                # AttributeError: 'str' object has no attribute 'get'
print(dict_d.get('D'))             # 4
print(dict_d.get(3))               # None : 없는 key이고, 미리 설정해둔 값도 없어서 None 리턴
print(dict_d.get(3, 'Nothing'))    # Nothing : 없는 key 여서 미리 설정해둔 값 리턴
dict_d.get('D') = 100   # SyntaxError: cannot assign to function call → 값 변경 불가
# slicing [시작:끝+1:역순?]
str_a = "12345"
print(str_a[-2:-4:-1])    # 43

tuple_a = tuple(str_a)
print(tuple_a[3:1:-1])    # ('4', '3')

list_a = list(str_a)
print(list_a[1:3])        # ['2', '3']

[Dict] key/value/둘 다 불러와 → return 새 객체 :

 └ dict_name.keys/values/items()

* return한 객체 ≠ Str List Tup Dict → 쓸 수 있는 함수나 method에는 제한적이므로 형변환을 하자

* for문 같은 반복구문 (iterate)에는 형변환 없이 사용가능 → for 별명 in 뭉탱이 :

* .items() → Tuple형 (key, value)가 한 요소인, Tuple형 아닌 객체 = 요소는 튜플인데, 객체 자체는 튜플아니라구


[Str] 특정 값으로 나눠줘 → return List형 객체 :

 └ str_name.split(값)

* 값을 입력하지않으면, 공백이나 탭등의 지표로 자동분할

str_a = "0 0 0"
str_b = '|'.join(str_a)
print(str_b)            # 0| |0| |0

list_a = str_b.split()
list_b = str_b.split('0')
list_c = str_b.split('|')

print(list_a)       # ['0|', '|0|', '|0'] → 띄어쓰기 기준 분할
print(list_b)       # ['', '| |', '| |', ''] → 0 기준 분할 : 0으로 시작/끝나니 맨앞/뒤 ''
print(list_c)       # ['0', ' ', '0', ' ', '0'] → (join의 값)| 기준 분할
print(list(str_a))  # ['0', ' ', '0', ' ', '0'] → 위와 같음

같은 위치의 값을 하나로 묶은 객체 줘 → return New 객체 :

 └ zip(값들)

* return한 객체 ≠ Str List Tup Dict → 쓸 수 있는 함수나 method에 제한적이므로 형변환을 하자

  + zip 후 dict로 형변환할꺼면, zip에 입력하는 뭉탱이는 무조건 2개(key뭉탱/value뭉탱)여야한다

  + for문 같은 반복구문 (iterate)에는 형변환 없이 사용가능 → for 별명들 in zip(값들):

name = ['KIM', 'JUNG']
age = [10, 20]
score = ('A', 'B')

print(zip(name, age))         # <zip object at 0x000002431AFD6D40> lis, tup 아닌 그냥 객체
print(list(zip(name, age)))   # [('KIM', 10), ('JUNG', 20)] → list형 객체 內 tuple형 요소
print(tuple(zip(name, age)))  # (('KIM', 10), ('JUNG', 20)) → tuple형 객체 內 tuple형 요소
print(dict(zip(name, age)))   # {'KIM': 10, 'JUNG': 20} → dict로 자동 변환

print(list(zip(name, age, score)))      # [('KIM', 10, 'A'), ('JUNG', 20, 'B')]
print(dict(zip(name, age, score)))      # dict만들꺼면 2뭉탱이(key뭉탱/value뭉탱)만 입력할 것
# ValueError: dictionary update sequence element #0 has length 3; 2 is required
# >>> {name: (age, score)}인 dict를 만들고 싶다면? → value 뭉탱이를 먼저 만들어
print(dict(zip(name, zip(age, score)))) # {'KIM': (10, 'A'), 'JUNG': (20, 'B')}

 

추가 관련

이 '값'을 추가해 → 기존 객체 변경 or return 새 객체 :

 └ [Str List Tup] : A + B → New object

  * A += B ≠ A = A + B

print("123" + "abc")    # 123abc
print((1, 2) + (3, 4))  # (1, 2, 3, 4)
print([1, 2] + [3, 4])  # [1, 2, 3, 4]
print({'A': 1} + {'C': 3})  # TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
print({1, 1} + {1, 2})      # TypeError: unsupported operand type(s) for +: 'set' and 'set'
print({1, 2} | {1, 2, 3})   # {1, 2, 3}

 └ [List] 맨 뒤, 값 1개 : list_name.append(값) → 기존 object의 변경

 └ [List] 맨 뒤, 값 N개 : list_name.extend([값들]) → 기존 object의 변경

  * A += B → A.extent(B)

 └ [Dict] : dict_name[New key] = New value

 └ [Dict Set] : object_name.update(값들) → 기존 object의 변경

dict_a = {'A': 1,
          'B': 2}
dict_b = dict_a

dict_b.update({'C': 3, 'D': 4})     # .update(dict형) 사용가능
dict_b.update('E' = 5, 'F' = 6)     
# SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

dict_b.update(E = 5, F = 6)         # .update(key = value) OK → {key: value}
# >>> Why can i use string without '' mark ? WHY?????????????????

print(dict_a)   # {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6}
print(dict_b)   # {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6}
# >>> 기존객체변경 & Alias

 └ [Set] : A | B → New object

  * 합집합 : A |= B ≠ A = A | B (집합.union(집합) → 새 객체)

  * 교집합 : A &= B ≠ A = A & B (집합.intersection(집합) → 새 객체)

  * 차집합 : A -= B ≠ A = A - B (집합.difference(집합) → 새 객체)

 └ [Set] : A .union(여러 값) → New object

  * A = A | B = A.union(B)

 └ [Set] 값 1개 : set_name.add(값) → 기존 object의 변경

  * A |= B = A.add(B) or A.update(B)

* Return 새로운 객체 → 객체의 type 확인 & 변수 재할당 必

[갖고 놀기]

str_a = "12"
str_b = str_a
str_b += "HI"            # Return New object
print(str_a, str_b)      # 12 12HI

list_a = ['A']
list_b = list_a
list_b += [1]            # Change the object
print(list_a, list_b)    # ['A', 1] ['A', 1] : Alias
list_b.append('B')       # Change the object
print(list_a, list_b)    # ['A', 1, 'B'] ['A', 1, 'B'] : Alias
list_b.extend([2, 'C'])  # Change the object
print(list_a, list_b)    # ['A', 1, 'B', 2, 'C'] ['A', 1, 'B', 2, 'C'] : Alias
list_b = list_b + [3]    # Return New object
print(list_a, list_b)    # ['A', 1, 'B', 2, 'C'] ['A', 1, 'B', 2, 'C', 3] : Not Alias

set_a = {1}
set_b = set_a
set_b |= {1, 2, 3}       # Change the object
print(set_a, set_b)      # {1, 2, 3} {1, 2, 3} : Alias
set_b.add(4)             # Change the object
print(set_a, set_b)      # {1, 2, 3, 4} {1, 2, 3, 4} : Alias
set_b.update({3, 4, 5})  # Change the object
print(set_a, set_b)      # {1, 2, 3, 4, 5} {1, 2, 3, 4, 5} : Alias

set_a = {1}
set_b = set_a
set_b.union({1, 2})           # Return New object
print(set_a, set_b)           # {1} {1} : Unchanged, because I didn't 
set_b = set_b.union({1, 2})   # Return New object
print(set_a, set_b)           # {1} {1, 2} : Net Alias

set_b = set_a                 # {1}
set_b = set_b | {1, 2, 3}     # Return New object
print(set_a, set_b)           # {1} {1, 2, 3} : Not Alias

이 '위치'에 이 '값'을 추가해 → 기존 객체 변경 :

 └ [List] : list_name.insert(index, value) → 기존 object의 변경

list_a = [0, 0, 0, 0]
list_b = list_a
list_b.insert(2, 'A')   # Change the object & 원래 그 자리에 있던 값은 '뒤'로 밀림
print(list_a, list_b)   # [0, 0, 'A', 0, 0] [0, 0, 'A', 0, 0] : Alias

이 값을 반복해 → 기존 객체 변경 or return 새 객체 :

 └ [Str List Tup] : A * int

str_a = '_'
str_b = str_a
str_b *= 5      # Return New object
print(str_a)    # _
print(str_b)    # _____ → Not alias

tuple_a = (1, 2)
tuple_b = tuple_a
tuple_b *= 2     # Return New object
print(tuple_a)   # (1, 2)
print(tuple_b)   # (1, 2, 1, 2) → Not alias

list_a = [1, 2]
list_b = list_a
list_b *= 2     # 기존 객체 변경
print(list_a)   # [1, 2, 1, 2]
print(list_b)   # [1, 2, 1, 2] → alias

dict_a = {'A': 1,
          'B': 2}
dict_b = dict_a
dict_b *= 2      # TypeError: unsupported operand type(s) for *=: 'dict' and 'int'
print(dict_a)
print(dict_b)

사이사이에 '값'을 추가해 → return New string type 객체 :

 └ [요소가 str type] : 추가하고 싶은 값.join(기존객체) → New string type 객체

list_a = ['a', 'b', 'c']
list_b = list_a
list_b = '|'.join(list_a)  # Return New object
print(list_a, list_b)      # ['a', 'b', 'c'] a|b|c : not Alias
print(type(list_b))        # 

int_a = 12345
print('|'.join(int_a))      # TypeError: can only join an iterable

* .join(입력값) : 객체type에 상관없이 요소들이 str type이면 됨.

 

삭제 관련

이 '자리'의 값을 없애줘 :

 └ [List Dict] del 객체[위치] → 기존객체변경

 └ [List Dict Set] 객체명.pop(위치) → 기존객체변경

  * del 객체[위치] ≒ 객체.pop(위치) → 기존 객체 변경

  * del 객체[위치] ≠ 객체.pop(위치) → return 삭제하는 값

  * 리스트.pop() → 맨 뒤 제거

# [String] 특정 자리(index)의 값 제거하기 : for i in range(, , )
str_a = 'ABC'
del str_a[0:2]      
# TypeError: 'str' object doesn't support item deletion >>> 실패

str_b = list(str_a)
del str_b[0:2]
str_b = str(str_b)
print(str_b)        # ['C'] >>> 실패 : list → str 형변환시 [, ] 까지 다 출력

str_b = ""
for i in range(2, len(str_a), 1):
    str_b += str_a[i]
print(str_b)        # C >>> 성공
# >>> str의 특정 자리의 값만 빼려면, for i in range()와 len(str)를 사용하는 수밖에 없나
# [Tuple] 특정 자리(index)의 값 제거하기 : List로 형변환 → 제거 → Tuple
tuple_a = (1, 2, 3, 4, 5)
tuple_a = list(tuple_a)
del tuple_a[3:5]                # >>> 실패
# TypeError: 'tuple' object doesn't support item deletion 
del tuple_a[3:len(tuple_a)]     # >>> 성공
tuple_a = tuple(tuple_a)
print(tuple_a)                  # (1, 2, 3)
# [List] 특정 자리(index)의 값 제거하기
list_a = [1, 2, 3, 4, 5]
list_b = list_a
del list_a[3:5]     # 기존 객체 변경
print(list_a)       # [1, 2, 3]
print(list_b)       # [1, 2, 3] → alias
# [Dict] 특정 자리(key)의 값 제거하기
dict_a = {'A': 1,
          'B': 2}
dict_b = dict_a
del dict_b['B']   # 기존 객체 변경
print(dict_a)     # {'A': 1}
print(dict_b)     # {'A': 1} → alias
# [Set] 특정 자리(값 자체)의 값 제거하기 → Set는 자리개념이 없음
set_a = {5, 2, 3, 4, 10}
# del set_a[1]   # TypeError: 'set' object doesn't support item deletion
set_a = list(set_a)
del set_a[1]     # → 2가 제거 될 것인가?
set_a = set(set_a)
print(set_a)     # {2, 10, 4, 5} >>> 실패
# >>> set은 값 제거로 하세요
# list.pop(index)
list_a = [1, 2, 3, 4, 5]
print(list_a.pop())     # 5 : 위치를 적지 않으면 맨 뒤 값 return
print(list_a)           # [1, 2, 3, 4] 기존 객체 변경
print(list_a.pop(0))    # 1 : return 제거되는 값
print(list_a)           # [2, 3, 4]
print(del (list_a[0])   # SyntaxError: invalid syntax

# set.pop()
set_a = {'A', 5, -1, 0, 1, 2, 10}
print(set_a.pop())      # 0 : 맨 뒤가 아니지만 → 이 pop엔 뭘 적으면 err
print(set_a)            # {'A', 2, 1, 5, 10, -1} : 정상작동

# dict.pop(key)
dict_a = {'A': 1,
          'B': 2,
          'C': 3}
print(dict_a.pop('C'))  # 사전.pop(키)
print(dict_a)           # {'A': 1, 'B': 2}

del dict_a['B']
print(dict_a)           # {'A': 1} → return을 하냐 마냐의 차이

이 '값'을 없애줘 :

 └ [List Set] .remove(값)

# [Str] 특정 '값' 제거 : list 형변환 → 실행 → 반복문으로 string
str_a = "ABC123=ABC123"
list_a = list(str_a)        # str → str 보다, list & count가 덜 복잡

for i in range(0, str_a.count('B'), 1):
    list_a.remove('B')      # 값 제거

for i in range(0, str_a.count('2'), 1):
    list_a.remove('2')      # 값 제거 : str을 형변환한 list라 숫자모양도 문자형

str_b = str()               # list → str 준비 : 그냥 형변환하면 원하는 대로 안 나옴
for i in range(0, len(list(list_a)), 1):
    str_b += list_a[i]

print(str_b)                # AC13=AC13 >>> 성공
# [Tup] 특정 '값' 제거 :  list 형변환 → 실행 → Tuple
tuple_a = (1, 2, 2, 3, 3, 3)
list_a = list(tuple_a)

for i in range(0, tuple_a.count(2), 1): # 중복여부
    list_a.remove(2)
tuple_a = tuple(list_a)
print(tuple_a)          # (1, 3, 3, 3) >>> 성공
# >>> 조건문을 사용하여, 중복이 아닐 땐 반복문을 거치지 않도록 하면 좀 더 효율적이지 않을까
# [List] 특정 '값'제거 : 해당 값 갯수확인.count → 해당 값 제거.remove
list_a = [1, 2, 3, 3, 3, 2]

for i in range(0, list_a.count(2), 1): # 중복여부 : 변하는 값(list_a.count(2)으로 해서 불편
    list_a.remove(2)

print(list_a)          # (1, 3, 3, 3) >>> 성공
# >>> 변하는 값이 range에 있는 경우, 시작할 때의 값으로 고정될까?

a = len(list_a)             # 4
for i in range(0, a, 1):    # a → 4회
    a = 1                   # a값이 변해도, 계속 4회일까?
    print(i, end=" ")       # 0 1 2 3 → 그러하다
# [Dict] 특정 '값'제거 : value로 key를 찾는 것을 안 배움 → 병렬형 진행 ?
dict_a = {'A': 1,
          'B': 2,
          'C': 2,
          'D': 3}
keys = list(dict_a.keys())
vals = list(dict_a.values())

for i in range(0, vals.count(2), 1):
    del keys[vals.index(2)]     # 위치로 제거
    vals.remove(2)              # 값으로 제거

dict_a = dict(zip(keys, vals))
print(dict_a)       # {'A': 1, 'D': 3} → 성공
# [Set] 특정 '값'제거 : 객체.remove(값)   ≠ del 객체[위치]
set_a = {3, 5, 6, 'a', 1}
set_b = set_a
set_b.remove(6)     # 해당 객체 변경
set_b.remove('a')
print(set_a)        # {1, 3, 5}
print(set_b)        # {1, 3, 5} → alias

 

* del 객체[위치] ≠ 객체.remove(값)


다 지워줘

 └ [List Dict Set] 객체명.clear()

 └ [All type] A = str/list/tuple/dict/set()

str_a = 'abcde'
list_a = [1, 2, 3, 4, 5]
tup_a = tuple(list_a)
dict_a = {'A': 1,
          'B': 2}
set_a = {'A', 5, -1, 0}

# str_a.clear()   # AttributeError: 'str' object has no attribute 'clear'
str_a = str()
print(str_a)      #

list_a.clear()
print(list_a)     # []

# tup_a.clear()   # AttributeError: 'tuple' object has no attribute 'clear'
tup_a = tuple()
print(tup_a)      # ()

dict_a.clear()
print(dict_a)     # {}

set_a.clear()
print(set_a)      # set()

[str]공백삭제

 └ str_name.strip/lstrip/rstrip()

str_a = "  ___  "       # 스페이스 바
print(str_a.lstrip())   # ___  : 좌 공백 삭제
print(str_a.rstrip())   #   ___: 우 공백 삭제
print(str_a.strip())    # ___ : 양쪽 공백 삭제

str_b = " _ "          # ㄱ 한자 1 특수문자
print(str_b.lstrip())   # _  : 좌 공백 삭제
print(str_b.rstrip())   #   _: 우 공백 삭제
print(str_b.strip())    # _ : 양쪽 공백 삭제
# >>> ㄱ 한자 1 도 삭제됨!!!!

 

수정 관련

이 '자리'의 값을 바꿔줘 :

 └ [List Dict] 객체명[index/key] = new value → 기존객체변경

 

이 ''을 다른 값으로 바꿔줘 :

 └ [string] 객체명.replace('A', 'B')

 

str_a = 'abcde'
str_a = str_a.replace('bcd', '12345')
print(str_a)                    # Return New object

list_a = [1, 2, 3, 4, 5]
list_a[1:3] = ['b', 'c', 'd']   # 갯수가 안 맞아도 됨
print(list_a)                   # 기존 객체 변경

tup_a = (5, 4, 3, 2, 1)
list_a = list(tup_a)
list_a[1:3] = ['b', 'c', 'd']
tup_a = tuple(list_a)
print(tup_a)

dict_a = {'A': 1, 'B': 2}
dict_a['A'] = 'a'               # 기존 객체 변경
print(dict_a)                   # {'A': 'a', 'B': 2}

set_a = {1, 2, 3}
set_a.remove(2)                 # 지우고
set_a.update('a', 'b', 'c')     # 추가
print(set_a)

[str] 대/소문자로 바꿔줘 :

 └ str_name.upper/lower() → return 새 객체

str_a = "ABCabc"
str_a.upper()           # Return New object, not 기존 값 변경
print(str_a)            # Unchanged
str_b = str_a.upper()   # 새 객체 → 변수에 재할당
print(str_b)            # ABCABC : 재할당 후 변수 출력
print(str_b.lower())    # abcabc : 새 객체 바로 출력

 

반응형

블로그의 정보

노력하는 실버티어

노실언니

활동하기