05. python 자료형 - chohankyun/python-django-study GitHub Wiki

##1.문자열(immutable: 변경되지 않는 문자열)

문자열 변경 불가능

greeting = 'hello world'   
greeting[0] = 'f'   

에러 발생

Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
TypeError: 'str' object does not support item assignment  

문자열 선언

작은 따옴표

'hello world!'  

큰 타옴표

"hello world!"  

작은 따옴표 3개

greeting = '''hello world,   
            I am a python programmer    
            in world'''  

' '(작은 따옴표)," "(큰 따옴표) 은 둘다 문자열 사용 가능
단 '(작은 따옴표)로 시작 하면 '(작은 따옴표 )로 끝내고,
"(큰 따옴표)로 시작 하면 "(큰 따옴표)로 끝내야 한다.
' '안에 " "를 쓸수 있고 " " 안에 ' '를 쓸수 있다.

''' '''(작은 따옴표 3개),""" """(큰 따옴표 3개) 은 docstring 으로 프로그램 안에서
여러열을 표현 할 수 있으며, 프로그램 설명에 쓰인다. 주석과 비슷한 성격이다.
물론 문자열 할당에도 사용 할 수 있다.

문자열 생성

greeting = 'hello world' # 할당 생성  
new_string = str('hello world') # 함수 사용 생성  
number_string = str(1234) # 문자형 변환  

문자열 인덱싱

greeting = 'hello world'  
greeting[3]  # l   
greeting[-1]  # d  

문자열의 각 문자를 순서로 접근이 가능하다.
순서는 0 부터 시작된다.

문자열 슬라이싱

greeting = 'hello world'  
greeting[0:3]  # hell  
greeting[1:]  # ello world  
greeting[:4]  # hello     
greeting[:-1]  # hello worl    

문자열 슬라이싱은 문자열이 인덱스에 의해 접근이 되기 때문에
인덱스를 사용해서 원하는 문자열만 접근 할 수 있다.

문자열 연산
더하기 연산 +

first = 'hello'  
second = ' world'  
greeting = first + second  
print(greeting) # hello world 출력  

곱하기 연산 *

print('=' * 50)  # = 이 50번 출력  

문자열 출력

greeting = '%s %s' % ('hello', 'world') # hello world 문자열 생성  
print('%s 입니다.' % '홍길동')  
print('%s 는 % 명입니다.' % ('홍길동', 1))  

print('%s' % greeting)  # hello world 출력  
print('홍길동', greeting) # 홍길동 hello world 출력   

문자열 함수
strip() : 양쪽 공백제거

greeting = ' hello '  
print(greeting.strip()) # 양쪽 공백제거 하고 hello 출력  

split() : 주어진 값으로 문자열을 나누고 리스트로 리턴, default = ' ' (공백)

greeting = 'hello world'  
greeting_s = greeting.split()  
print(greeting_s) # ['hello','world']  

in 연산 : 문자열 안에 값이 있는지 검사

greeting = 'hello world'  
print('hello' in greeting)  # True 출력  

lower() : 대문자를 소문자로 바꿈
upper() : 소문자를 대문자로 바꿈
encode() : 스트링을 바이트(bytes:변경 불가능한 바이트 배열)로 변환

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(str) # str 클래스 설명 (함수 포함) 출력   
>>> dir(str) # str 객체의 변수와 함수를 출력   

문자열 결합 성능 테스트 참고 문서

##2.bytearray(mutable: 변경 가능한 바이트 배열)

bytearray 선언

greeting = bytearray(b'hello world')  
print(greeting) # bytearray(b'hello world') 출력   

변경 가능

greeting[2] = 105  # 숫자로만 입력 가능   
print(greeting)  # bytearray(b'heilo world') 출력, 3 번째 l -> i 변경(mutable)          

바이트에 들어갈 값은 0 <= x < 256

wiki = bytearray([119,105,107,105])  # 바이트에 들어갈 값은 0 <= x < 256  
print(wiki) # bytearray(b'wiki') 출력  

바이트는 0~255 까지 ascii 값만 표현 하므로 한글은 넣을수 없음

greeting = bytearray(b'안녕')  

에러발생

 Traceback (most recent call last):  
 File "<stdin>", line 1, in <module>  
 ValueError: byte must be in range(0, 256)  

bytearray 함수
decode() 바이트를 문자열로 변환

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(bytearray) # bytearray클래스 설명 (함수 포함) 출력   
>>> dir(bytearray) # bytearray객체의 변수와 함수를 출력   

##3.bytes(immutable : 변경되지 않는 바이트 배열)
bytes 선언
문자를 사용 할때는 앞에 b 를 붙인.

greeting = b'hello world' # 이렇게 선언하면 bytearray 가 아닌, bytes 가 됨  
print(greeting) # b'hello world' 출력   
obj_greeting = bytes(b'hello world')  
print(obj_greeting) # b'hello world' 출력   

변경 불가능

greeting[2] = 105  # 숫자로만 입력 가능   

에러 발생

Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
TypeError: 'bytes' object does not support item assignment         

바이트에 들어갈 값은 0 <= x < 256

wiki = bytes([119,105,107,105])
print(wiki) # b'wiki' 출력  

바이트는 0~255 까지 ascii 값만 표현 하므로 한글은 넣을수 없음

##4.list (mutable: 변경 가능한 리스트, 혼합 데이터 가능)
리스트 선언(가장 많이 사용되는 자료형)

greeting_s =[] # 비어있는 리스트    
greeting_s = list() # 비어있는 리스트  
greeting_s = ['hello','world','!'] # ,구분으로 데이터를 나열   
greeting_s = [4.0,'string',True] # 다양한 자료형 입력 가능   
greeting_s = [x for x in range(0,4,1)] # 리스트 내포 (list Comprehension)   

list Comprehension(리스트 내포?)
한국말이 더 어렵네, '종합적 리스트' 또는 '포괄적 리스트'
이말이 더 나은것 같다.

리스트 인덱싱

greeting_s = ['hi','hello','good morning', 'good afternoon', 'good evening']    
greeting_s[3]  # 0 시작, good afternoon   
greeting[-1]  # good evening  

리스트는 인덱스를 통해서 접근이 가능하다.
순서는 0 부터 시작된다.

리스트 슬라이싱

greeting_s = ['hi','hello','good morning', 'good afternoon', 'good evening']    
greeting_s[0:3]  # ['hi','hello','good morning']     
greeting_s[1:]  # ['hello','good morning', 'good afternoon', 'good evening'] 
greeting_s[:2]  # ['hi','hello']       
greeting_s[:-1]  # ['hi','hello','good morning', 'good afternoon']    

리스트 슬라이싱은 리스트가 인덱스에 의해 접근이 되기 때문에
인덱스를 사용해서 원하는 리스트 값 만 접근 할 수 있다.
greeting_s[1:3] 1은 포함, 3은 비 포함

리스트 연산
더하기 연산 +

small_number_s = [1,2,3,4]  
big_number_s = [5,6,7,8,9] 
small_number_s + big_number_s # [1,2,3,4,5,6,7,8,9]  

곱하기 연산 *

small_number_s = [1,2,3]  
small_number_s *3 # [1,2,3,1,2,3,1,2,3]  

리스트 변경 및 삭제

small_number_s = [1,2,3]  
small_number_s[1] = 4  # 인덱스로 접근해서 수정  
small_number_s # [1,4,3]  
del small_number_s[1] # del 명령어를 사용  
small_number_s # [1,3]  

리스트 함수

append() : 리스트 끝에 값을 추가

small_number_s = [1,2,3]  
small_number_s.append(4)  
small_number_s # [1,2,3,4]  
small_number_s.append([5,6])  
small_number_s # [1,2,3,4,[5,6]] 

extend() : 리스트 끝에 리스트 추가

small_number_s = [1,2,3]  
small_number_s.extend([4,5,6])  
small_number_s # [1,2,3,4,5,6]  

sort() : 리스트 정렬

small_number_s = [1,3,6,9,4,5]  
small_number_s.sort()  
small_number_s # [1,3,4,5,6,9]  

param : key(리스트 값에서 원하는 값을 키로 해서 정렬), reverse(True= 역방향, False = 순방향)
key 예) sort_second_value()

def sort_second_value(list_value):  
    return list_value%10    

number_value_s = [11,92,74,33,57,88,77,12,23]  
number_value_s.sort(key=sort_second_value)  
number_value_s = [11,92,12,33,23,74,57,77,88]  

reverse() : 역방향 정렬

index() : 요서를 통한 index 접근

number_value_s = [11,92,74,33,57,88,77,12,23]  
number_value_s.index(92) # 1  

insert() : 원하는 위치에 값 삽입

number_value_s = [11,22,33,99]  
number_value_s.insert(0,9)  
number_value_s # [9,11,22,33,99]  

remove() : 원하는 값을 제거함 (입력된 값이 제일 처음 나오는 값만 제거)

number_value_s = [11,22,33,44,22,22]  
number_value_s.remove(22)  
number_value_s # [11,33,44,22,22]     

pop() : 원하는 값을 빼내고, 값을 제거함 (인덱스 default=last )

number_value_s = [11,22,33,44,22,22]  
number_value_s.pop() # 22   
number_value_s # [11,22,33,44,22]     

count() : 리스트에 원하는 값이 몇개인지 개수를 리턴

number_value_s = [11,22,33,44,22,22]  
number_value_s.count(22) # 3  

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(list) # list클래스 설명 (함수 포함) 출력   
>>> dir(list) # list객체의 변수와 함수를 출력   

##5.tuple (immutable : 변경되지 않는 리스트, 혼합 데이터 가능)
리스트와 거의 유사하고 변경 할 수 없는 데이터

튜플선언

char_value_s = ()  # 비어있는 튜플  
char_value_s = tuple() # 비어있는 튜플   
char_value_s = ('hi',) # 요소가 하나일때 "," 뒤에 붙임      
char_value_s = ('hi','hello','hello world')  
char_value_s = 'hi', 'hello', 'hello world'  # "()" 없이도 선언 가능    

char_value_s = ('hi') # "," 없이 하나의 요소 선언   
print(type(char_value_s)) # <class 'str'> 문자열 타입  

** 튜플 변경 및 삭제 불가능**

char_value_s = ('hi', 'hello', 'hello world')  
del char_value_s[1]  

Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
TypeError: 'tuple' object doesn't support item deletion  

char_value_value_s[1] = 'good'  

Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
TypeError: 'tuple' object does not support item assignment  

튜플 인덱싱

greeting_s = ('hi','hello','good morning', 'good afternoon', 'good evening')    
greeting_s[3]  # 0 시작, good afternoon   
greeting[-1]  # good evening  

튜플은 인덱스를 통해서 접근이 가능하다.
순서는 0 부터 시작된다.

튜플 슬라이싱

greeting_s = ('hi','hello','good morning', 'good afternoon', 'good evening')    
greeting_s[0:3]  # ('hi','hello','good morning')     
greeting_s[1:]  # ('hello','good morning', 'good afternoon', 'good evening')   
greeting_s[:2]  # ('hi','hello')       
greeting_s[:-1]  # ('hi','hello','good morning', 'good afternoon')    

튜플 슬라이싱은 튜플이 인덱스에 의해 접근이 되기 때문에
인덱스를 사용해서 원하는 튜플 값 만 접근 할 수 있다.
greeting_s[1:3] 1은 포함, 3은 비 포함

튜플 연산
더하기 연산 +

small_number_s = (1,2,3,4)  
big_number_s = (5,6,7,8,9) 
small_number_s + big_number_s # (1,2,3,4,5,6,7,8,9)  

곱하기 연산 *

small_number_s = (1,2,3)  
small_number_s *3 # (1,2,3,1,2,3,1,2,3)  

튜플 함수
index() : 요소를 통한 index 접근

number_value_s = (11,92,74,33,57,88,77,12,23)  
number_value_s.index(92) # 1  

count() : 튜플에 원하는 값이 몇개인지 개수를 리턴

number_value_s = (11,22,33,44,22,22)  
number_value_s.count(22) # 3     

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(tuple) # tuple클래스 설명 (함수 포함) 출력   
>>> dir(tuple) # tuple객체의 변수와 함수를 출력   

##6.set(mutable : 변경 가능한 집합, 순서가 정해지지 않은 집합. 중복 허용 안 함)
set 선언

number_value_s = {1,2,3}  
number_value_s = set([1,2,3])  
number_value_s = set((1,2,3))  

set 중복 허용 안함 그리고 순서없음(unordered)

number_value_s = {1,2,3,4,4,5,5}  
number_value_s # {1,2,3,4,5}  
char_value_s = set('hello')  
char_value_s # {'e','l','o','h'}  

set 활용(활용도가 별로 없음)

교집합(&,intersection)

number_value_1_s = {1,2,3,4,5,6,7}  
number_value_2_s = {4,5,6,7,8,9}  
number_value_1_s & number_value_2_s # {4,5,6,7}  
number_value_1_s.intersection(number_value_2_s)  # {4,5,6,7}  

합집합(|,union)

number_value_1_s = {1,2,3,4,5,6,7}  
number_value_2_s = {4,5,6,7,8,9}  
number_value_1_s | number_value_2_s # {1,2,3,4,5,6,7,8,9}  
number_value_1_s.union(number_value_2_s) # {1,2,3,4,5,6,7,8,9}  

차집합(-,difference)

number_value_1_s = {1,2,3,4,5,6,7}  
number_value_2_s = {4,5,6,7,8,9}  
number_value_1_s - number_value_2_s # {1,2,3}  
number_value_1_s.difference(number_value_2_s) #{1,2,3}  

set 함수
add() : 한개의 값 추가

number_value_s = {1,2,3}  
number_value_s.add(4) 
number_value_s # {1,2,3,4}  

update() : 여러개의 값 추가

number_value_s = {1,2,3}  
number_value_s.update([4,5,6,7])  
numberr_value_s # {1,2,3,4,5,6,7}  

remove() : 한개의 값 삭제

number_value_s = {1,2,3,4}  
number_value_s.remove(4)  
number_value_s # {1,2,3}  

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(set) # set 클래스 설명 (함수 포함) 출력   
>>> dir(set) # set 객체의 변수와 함수를 출력   

##7.frozenset(immutable: 변경되지 않는 집합, 순서가 정해지지 않은 집합. 중복 허용 안 함)
frozenset 선언

number_value_s = frozenset([1,2,3])  
number_value_s = frozenset((1,2,3))  

frozenset 중복 허용 안함 그리고 순서없음(unordered)

number_value_s = frozenset([1,2,3,4,4,5,5])    
number_value_s # frozenset({1,2,3,4,5})  
char_value_s = frozenset('hello')  
char_value_s # frozenset({'e','l','o','h'})  

frozenset 활용(활용도가 별로 없음)
교집합(&,intersection)

number_value_1_s = frozenset([1,2,3,4,5,6,7])  
number_value_2_s = frozenset([4,5,6,7,8,9])  
number_value_1_s & number_value_2_s # frozenset({4,5,6,7})  
number_value_1_s.intersection(number_value_2_s)  # frozenset({4,5,6,7})  

합집합(|,union)

number_value_1_s = frozenset([1,2,3,4,5,6,7])  
number_value_2_s = frozenset([4,5,6,7,8,9])  
number_value_1_s | number_value_2_s # frozenset({1,2,3,4,5,6,7,8,9})  
number_value_1_s.union(number_value_2_s) # frozenset({1,2,3,4,5,6,7,8,9})  

차집합(-,difference)

number_value_1_s = frozenset([1,2,3,4,5,6,7])  
number_value_2_s = frozenset([4,5,6,7,8,9])  
number_value_1_s - number_value_2_s # frozenset({1,2,3})  
number_value_1_s.difference(number_value_2_s) # frozenset({1,2,3})  

frozenset 함수

참고: add() 없음

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(frozenset) # frozenset 클래스 설명 (함수 포함) 출력   
>>> dir(frozenset) # frozenset 객체의 변수와 함수를 출력   

##8.dict(mutable : 변경 가능한 키/값 쌍)

key, value 한 쌍의 값으로 구성
key 는 immutable(변경되지 않는) 값만 사용
value 는 제약 사항 없음

str_number_s = {[1,2]:'hello'} # error 발생   

File "<stdin>", line 1, in <module>  
TypeError: unhashable type: 'list'  

str_number_s = {(1,2):'hello'} # key 사용 가능    

dict 선언

str_number_s = {}  # 비어 있는 딕션너리  
str_number_s = dict() # 비어 있는 딕션너리    

str_number_s = {'one':1, 'two':2} # {'one':1, 'two':2}  
str_number_s = dict([('one',1),('two',2)]) # {'one':1, 'two':2}    
str_number_s = dict('one'=1,'two'=2) # {'one':1, 'two':2}      

str_number_s = {1:'one', 2:'two'}  # {1:'one', 2:'two'}  
str_number_s = dict([(1,'one'),(2,'two')]) # {1:'one', 2:'two'}  

str_number_s = dict(1='one',2='two')  # error 발생  
File "<stdin>", line 1  
SyntaxError: keyword can't be an expression # error 발생 원인 아직 잘 모름   

{} 로 생성하는 것이 dict 으로 생성 하는것 보다 성능이 더 좋다

dict 값

str_number_s = {1:'one', 2:'two'}  
str_number_s[1] # 'one'    
str_number_s.get(1) # 'one'    

str_number_s[3]  #  error 발생   
File "<stdin>", line 1, in <module>
KeyError: 3

str_number_s.get(3) # None 리턴  

값을 가져올때 항상 존재 하는 값이면 [] 사용
값을 가져올때 존재하지 않을 수 있다면 get

dict 값 추가

str_number_s = {1:'one'} # 초기화 및 값 추가  
str_number_s[2] = 'two' # 값 추가  
str_number_s # {1:'one', 2:'two'}  

dict 값 삭제

str_number_s = {1:'one',2:'two'}  
del str_number_s[2]  
str_number_s # {1:'one'}  

dict 선언 시 주의 사항
키를 중복으로 사용하면 마지막 값만 적용

str_number_s = {1:'one', 1:'two'}  
str_number_s # {1:'two'}  

dict 함수
keys() : 키 호출

str_number_s = {1:'one',2:'two'}  
str_number_s.keys() # dict_keys([1,2])  

get() : 키 사용 값 호출

str_number_s = {1:'one',2:'two'}  
str_number_s.get(1) # 'one'  

values() : 값 호출

str_number_s = {1:'one',2:'two'}  
str_number_s.values() # dict_values(['one','two'])  

items() : 키, 값 호출

str_number_s = {1:'one',2:'two'}  
str_number_s.itmes() # dict_items([(1, 'one'), (2, 'two')])  

clear() : 모두 지움

str_number_s = {1:'one',2:'two'}  
str_number_s.clear() # {}  

in 사용

str_number_s = {1:'one',2:'two'}  
2 in str_number_s # True (key 를 비교)  

ETC : interatice mode 에서 help 또는 dir 사용

>>> help(dict) # dict 클래스 설명 (함수 포함) 출력   
>>> dir(dict) # dict 객체의 변수와 함수를 출력   

##9.int(immutable: 변경되지 않는 정수, 크기는 무제한)
int 선언

number = 1  
number = int(1)    
number = int('1')
number = int('1',base=0) # base = 0  첫 파라미터 문자열 숫자를 보고 진수 판단      
number = int('1',base=10) # base = 10 첫 파라미터 십진수  
number = int('1',base=8) # base = 8 첫 파라미터 8진수  

base = 10
int() 함수 default base = 0

number = int('0o10',base=0) # 0o10 8진수  
number # 8  
number = int('0x10',base=0) # 0x10 16진수  
number # 16  

int 함수
interatice mode 에서 help 또는 dir 사용

>>> help(int) # int 클래스 설명 (함수 포함) 출력   
>>> dir(int) # int 객체의 변수와 함수를 출력   

##10.float(immutable: 변경되지 않는 부동소수점 수)
float 선언

number = 0.12  
number = 1.2E-1 #  지수 표현  
number = float(0.12)  
number = float('0.12') # 문자열 숫자 입력 가능  

float 함수
ETC : interatice mode 에서 help 또는 dir 사용

>>> help(float ) # float 클래스 설명 (함수 포함) 출력   
>>> dir(float ) # float 객체의 변수와 함수를 출력   

python 3 에서 반올림이 우리가 알고 있는 것과 다름
일반적 반올림 : half up

1-4 버림  
5-9 올림  

예) 2.4 반올림 2.0  
    2.5 반올림 3.0  

python 3 default 반올림 : half to even

1-4 버림    
6-9 올림  
5 일때 half to even  적용  

예) 2.4 반올림 2.0  
    2.6 반올림 3.0
    2.5 반올림 2.0 # 반올림 시 올림 값이 짝수 일때만 올림, 홀수 일때는 버럼   
    1.5 반올림 2.0  
    3.5 반올림 4.0  
    4.5 반올림 4.0  

부동소수점 오차

부동소수점 오차 : float 연산에 존재(언어전 문제 아님, 컴퓨터 문제)  
컴퓨터는 실수를 고정소수점 으로 저장 할 수 없음,  
그래서 실수를 부동소수점 방식으로 저장함,  
작은 비트 수를 가지고 넓은 범위의 실수를 표현하기 때문에,    
표현 할 수 없는 실수가 생김,  
결론적으로 컴퓨터는 실수를 99,9% 적확하기 표현 한다고 함,  
100% 정확한 값이 아님  

부동소수점 오차 참고

Python 에서 금액 또는 정확한 숫자 처리를 원한다면

Decimal 모듈을 사용하면 됨,    
Decimal 모듈을 사용하면, 반올림도 원하는 방식으로 사용 할 수 있음,  
Python round 함수의 default 는 half to even,  
Decimal 모듈을 사용해서 반올림 연산의 방식으로 half up 으로 설정 가능,  
또한 부동소수점 오차 없이 실수를 표현 할수 있음.  
단 Decimal 모듈 사용 시 성능 저하 발생  

##11.complex(immutable: 변경되지 않는 복소수)
복소수 선언

c_number = 3 + 4j # (3+4j)   
c_nmuber = complex(3,4)  # (3+4j)      

복소수 함수
ETC : interatice mode 에서 help 또는 dir 사용

>>> help(complex) # complex 클래스 설명 (함수 포함) 출력    
>>> dir(complex) # complex 객체의 변수와 함수를 출력  

복소수를 어디에 쓰는지 모르겠음

##12.bool(immutable: 변경되지 않는 진리값)
bool 선언

bool_value = True  
bool_value = False   
bool_value = bool(True)  
bool_value = bool(False)  
bool_value = bool(1) # True  
bool_value = bool(0) # False  

bool 선언 시 문자열은 의미 없음
문자는 모두 True 로 리턴

bool_value = bool('True')  # True  
bool_value = bool('False') # True  
bool_value = bool('hello') # Trrue  

bool 함수
ETC : interatice mode 에서 help 또는 dir 사용

>>> help(bool) # bool 클래스 설명 (함수 포함) 출력    
>>> dir(bool) # bool 객체의 변수와 함수를 출력  

##13. ==(equality) vs is(identity)
is 의 결과 값은 우리가 예상 하지 못하는 결과를 얻을 수 있다
그러므로 내용을 비교 하려면 == 을 써야 한다.
== 두 변수가 참조 하는 객체의 값이 같냐?(값이 같냐)
is 두 변수가 참조 하는 객체의 주소가 같냐?(주소가 같냐)

greeting_1 = 'hello world!'  
greeting_2 = 'hello world!'  

print('greeting_1 객체 내용: %s' % greeting_1)  
print('greeting_2 객체 내용: %s' % greeting_2)  
print('greeting_1 객체 주소: %s' % id(greeting_1))  
print('greeting_2 객체 주소: %s' % id(greeting_2))  

if greeting_1 == greeting_2:  
    print('same')  
else:  
    print('diff')  

if greeting_1 is greeting_2:  
    print('same')  
else:  
    print('diff')  

greeting_3 = 'hello world!'[:5]  
greeting_4 = 'hello world!'[:5]  

print('greeting_3 객체 내용: %s' % greeting_3)  
print('greeting_4 객체 내용: %s' % greeting_4)  
print('greeting_3 객체 주소: %s' % id(greeting_3))  
print('greeting_4 객체 주소: %s' % id(greeting_4))  

if greeting_3 == greeting_4:  
    print('same')  
else:  
    print('diff')  

if greeting_3 is greeting_4:  
    print('same')  
else:  
    print('diff')  
⚠️ **GitHub.com Fallback** ⚠️