타리스만

[파이써닉 pythonic 코드] list comprehension, split, join, enumerate, zip

파이써닉 코드, pythonic code란 파이썬 스타일의 코드를 말한다. 파이썬 스타일의 코드라는건 무엇인가 말그대로 파이썬스럽다는 의미이다. 파이썬 느낌이 나는 세련된 코드? 라고 할 수도 있겠다. 파이썬 특유의 문법을 활용해서 잘 만든 센스있는 코드.

 

why pythonic code?

옛날 프로그래밍 언어들은 컴퓨터의 연산속도를 고려하여 수행능력을 높이는데 초점을 두었다. 하지만 지금은 컴퓨팅 능력이 기하급수적으로 발달해서 현재의 프로그래밍에서는 개발자의 편의성이 더 중요해졌다. 코딩하는 사람이 편하게 효율적으로 일해야 더 좋은 결과물이 나오니깐.

 

그러한 관점에서 파이썬이 유용한 프로그래밍 툴이라 대세가 된 것이고 따라서 그런 파이썬의 장점을 십분 활용하는 것이 코딩을 잘하는 방법이다.

 

그밖에 pythonic code를 사용하는 이유들

복잡하고 고급스러운 코드를 작성해야 할 수록 파이써닉 코드가 더욱 필요해진다.

다른 사람이 짜놓은 코드를 이해하기 위해서 필요하다. (대부분의 개발자들이 파이썬 스타일로 코드를 짜기 때문에)

더 빠르고 효율적인 코딩을 작성할 수 있다.

보기에도 간결해보이고 있어보인다 (간지난다)

 

기본적인 pythonic code 종류들

Split & Join

List Comprehension

Enumerate & Zip

Map & Reduce

Asterisk

 

 

 

join

리스트의 원소들을 합쳐서 하나의 문자열로 만드는 작업을 한다고 해보자.

a = ['KOREA','JAPAN','CHINA']
result = ''
for i in a:
	result += i
result
'KOREAJAPANCHINA'    ##결과

기본적인 for 반복문을 써서 만들면 위와 같이 될 것이다.

 

이것을 pythonic code로 만들면

a = ['KOREA','JAPAN','CHINA']
result = ''.join(a)
result
'KOREAJAPANCHINA'    ##결과

이렇게 join 함수를 써서 한줄로 간단히 만들 수 있다. result를 빈칸으로 정의함과 동시에 a에 있는걸 join해서 넣으라는 명령까지 함께 전달하는 것이다. 이런 식으로 만드는 것을 pythonic code라고 한다.

 

a = ['KOREA','JAPAN','CHINA']
'-'.join(a)

'KOREA-JAPAN-CHINA'    ##결과

join을호 합칠 때 이렇게 연결부호를 입력해서 붙일수도 있다.

 

 

split

join과 반대로 문자열을 분리하는 함수이다. 예를 들면 노래가사나 연설문 같은 텍스트 안에 특정 단어가 몇 번 언급되었는지를 계산한다던지 할 때 먼저 텍스트 덩어리를 각 단어로 분리해야 할 것이다.

 

test="korean,english,japanese,chinese"
test.split(",")

['korean', 'english', 'japanese', 'chinese']  ##결과

설명이 필요없을 정도로 사용방법이 간단하다. 변수명.split("구분자") 형태로 입력하면 나눠서 각각을 원소로 하는 리스트 형태로 반환해준다.

 

test="korean,english,japanese,chinese"
a,b,c,d=test.split(",")
print(a,b,c,d)

korean english japanese chinese    ##결과

split으로 나누면서 변수명을 할당해서 나눈 원소들이 각각의 새로운 변수로 할당되도록 해줄수도 있다.

 

 

 

list comprehension

다음은 리스트를 파이썬 스타일로 만드는 방법이다. pythonic code 중에서 가장 중요한 부분이라고 할 수 있다.

 

1부터 10까지의 숫자를 원소로 하는 리스트를 만든다고 하자.

result = []
for i in range(1,11):
    result.append(i)
result

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]    ##결과

이렇게 range로 돌릴 숫자 범위를 지정해주고, for loop 반복문으로 숫자 하나씩 result 리스트 변수에 append 되도록 하면 된다. append는 리스트 공부할때 봤던 새로운 원소를 리스트의 마지막에 추가시키는 함수이다.

 

 

 

[파이썬] 리스트 총정리 인덱스찾기, append 추가함수, 정렬, 2차원구조

지난 시간에 파이썬의 변수 개념과 몇가지 기본적인 자료형, 수치형 (정수형 실수형) 문자형 논리형(불리언) 에 대해 알아보았다. [파이썬] 변수 개념, 자료형 타입 확인과 변환 (숫자, 문자, 논리

tali.tistory.com

 

이것을 list comprehension 파이썬 스타일 코드로 만들면 어떻게 바꿀 수 있을까.

 

result = [i for i in range(1,11)]
result

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]   ##결과

이렇게 for문을 리스트 안에 넣어버리면 리스트 원소가 이런 것이다 하고 바로 지정해버릴 수 있다. 이것이 파이썬 스타일 코딩인 list comprehension이다.

 

nested loop

word1 = "Hello"
word2 = "World"

print([i + j for i in word1 for j in word2])

## 결과
['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od']   

for문을 두개 결합하여 위와 같이 만들수도 있다. 리스트 [ ] 안에 원소는 i+j가 되는데

 

for i in word1

for j in word2

이중 반복문 구조로 먼저 i가 word1에서 하나 할당된 후 그 때 word2에서 j를 하나씩 가져오면서 한번 싹 매칭시키고 word1의 다음 i에 대해 또 j 를 한번씩 반복하는 식이다.

 

알아보기 쉽게 원래의 for 반복문 구조로 풀어서 쓰면 아래와 같다.

word1 = "Hello"
word2 = "World"

result=[]
for i in word1:
    for j in word2:
        result.append(i+j)
print(result)

## 결과
['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od']

for문이 하나 있고 하부구조에서 하나가 더 돌아가는 셈이다. 이것은 일전에 for 반복문 공부할때 봤던 중첩루프 nested loop 구조이다. 생각이 안나면 아래 링크를 복습

 

https://tali.tistory.com/1302#head4

 

[파이썬] 반복문 : for문 while문 기초와 응용, break continue else

파이썬 구문 (statement) 학습 오늘은 반복문에 대해 알아본다. 반복문은 말 그대로 정해진 어떠한 동작을 반복적으로 수행하도록 만드는 명령문이다. [파이썬] if문 elif else로 조건문 여러개, and or n

tali.tistory.com

(티스토리 블로그 링크걸때 목차 헤드 지정된 상태에서 걸어놓으면 바로 본문 중 해당 위치로 이동되네 오 굿...)

 

리스트 조건추가

또한 리스트 형성시 if 조건문을 같이 넣어서 필터링 기능도 추가해줄 수 있다.

case1 = ["A","B","C"]
case2 = ["D","E","B"]

result = [i + j for i in case1 for j in case2 if not(i=="B")]
result

##결과
['AD', 'AE', 'AB', 'CD', 'CE', 'CB']

이렇게 뒤에다 if를 붙여서 특정 조건일 때, 또는 뭐는 빼고 등등 필터링을 해줄 수 있다. 위에서는 case1에서 B를 포함하지 않도록 해주었고 그래서 결과를 보면 앞자리가 A랑 C만 있는것을 볼 수 있다.

 

2 dimensional list

2차원 리스트도 파이써닉 코드를 이용해서 생성할 수 있다. 2차원 리스트도 예전에 리스트 학습때 봤던 개념이니 기본적인 내용은 아래 링크를 참조

 

https://tali.tistory.com/1285#head5

 

[파이썬] 리스트 총정리 인덱스찾기, append 추가함수, 정렬, 2차원구조

지난 시간에 파이썬의 변수 개념과 몇가지 기본적인 자료형, 수치형 (정수형 실수형) 문자형 논리형(불리언) 에 대해 알아보았다. [파이썬] 변수 개념, 자료형 타입 확인과 변환 (숫자, 문자, 논리

tali.tistory.com

 

어떤 문자열 원소들로 구성된 리스트가 있을 때 각 단어를 대문자,소문자,글자수로 표시하는 리스트를 만들어보자.

country = ["Korea","Japan","China"]

result = [ [i.upper(), i.lower(), len(i)] for i in country ]
result

## 결과
[['KOREA', 'korea', 5], ['JAPAN', 'japan', 5], ['CHINA', 'china', 5]]

이렇게 [대문자,소문자,글자수]로 표시하는 리스트를 하나 지정하고 그 리스트의 i 자체가 country 에서 하나씩 불러오면서 for반복문을 돌도록 하면 country 원소 개수만큼의 하부 리스트를 가지는 이차원 리스트가 형성된다.

 

1차원 리스트와 2차원 리스트의 차이

case1 = ["A","B","C"]
case2 = ["D","E","B"]

result1 = [ i + j for i in case1 for j in case2 ]
print(result1)

result2 = [ [ i + j for i in case1 ] for j in case2 ]
print(result2)


## 결과
['AD', 'AE', 'AB', 'BD', 'BE', 'BB', 'CD', 'CE', 'CB']
[['AD', 'BD', 'CD'], ['AE', 'BE', 'CE'], ['AB', 'BB', 'CB']]

위에서 만든 nested loop 리스트를 2차원 리스트가 되도록 괄호를 추가해주었다. result2를 보면 case2의 j가 먼저 하나 할당되고 하부 리스트인 i+j를 수행하게 된다. 즉 여기서는 case2 j에 대해 case1의 i를 각각 매칭시켜서 하나의 리스트로 만들고 다시 다음 j에 대해 하위 리스트를 만드는 식이다.

 

 

Enumerate

리스트에서 원소 (Element) 값을 추출할 때 인덱스 번호를 매겨서 뽑아준다. 바로 예제를 통해 익혀본다.

 

기본적인 사용법

for i, v in enumerate(["A","B","C"]):
    print (i,v)
    
## 결과
0 A
1 B
2 C

기본적으로는 이렇게 사용한다. enumerate(어떤 리스트) 형태로 입력하면 0,첫번째 원소 1,두번째 원소 2,세번째 원소 식으로 값을 추출해 준다.

 

list(enumerate("ABCD"))

## 결과
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]

그냥 enuemrate(값) 으로만 입력하면 <enumerate at 0x20808056140> 이런 형태로 값을 주기 때문에 어떤 식으로 출력할지 리스트같은 형태로 지정을 해주어야 한다.

 

사전형태로 만들기

a="ABCD"
{i : v for i , v in enumerate(a)}

## 결과
{0: 'A', 1: 'B', 2: 'C', 3: 'D'}

이렇게 사전 (dictionary) 형태로 지정해서 인덱스 번호와 원소값이 key:value 쌍이 되도록 지정해 줄 수도 있다. 사전에 대한 내용 복습은 아래 링크를 참고

 

 

[파이썬] 딕셔너리 (Dictionary) 사전자료형 선언과 key:value 연산

리스트(list), 튜플(tuple), 집합(set) 자료형에 이어서 오늘은 딕셔너리 (Dictionary), 사전 자료형에 대해 알아본다. 사전의 특징 사전의 특징은 데이터를 저장할 때 구분자를 함께 묶어서 저장해준다

tali.tistory.com

 

단어 스플릿과 응용

text="Pectus excavatum, also referred to as “sunken chest,” is a depression in the chest wall."
{i : v.lower() for i, v in enumerate(text.split())}

## 결과
{0: 'pectus',
 1: 'excavatum,',
 2: 'also',
 3: 'referred',
 4: 'to',
 5: 'as',
 6: '“sunken',
 7: 'chest,”',
 8: 'is',
 9: 'a',
 10: 'depression',
 11: 'in',
 12: 'the',
 13: 'chest',
 14: 'wall.'}

split과 같이써서 이렇게 단어별로 만들어 줄 수도 있다. 위 명령어의 동작 순서를 풀어보면 아래와 같다.

 

1) 어떤 텍스트 단락을 문자형 변수로 지정해놓고,

2) 변수명.split 으로 단어별로 짤라준 뒤

3) 거기에 enumerate를 씌워서 인덱스 번호와 원소 쌍으로 값을 추출

4) 그것을 key:value 쌍의 사전 형태로 저장하여 출력

 

 

zip

두 개 이상의 리스트에서 같은 인덱스 번호에 있는 원소 (element) 값들을 병렬적으로 묶어서 추출해주는 기능이다.

 

기본적인 사용법

 

a = ["a1","b1","c1"]
b = ["a2","b2","c2"]

for a,b in zip(a,b):
    print(a,b)
    
## 결과
a1 a2
b1 b2
c1 c2

이렇게 zip(변수1, 변수2) 형태로 지정하면 각 리스트형 변수들에서 같은 인덱스 위치에 있는 원소들끼리 묶어서 추출해준다.

 

만약 b 리스트에는 c2가 없어서 원소 개수가 하나 적다면? 그러면 같은 인덱스 번호의 원소를 뽑을 수 있는 b2 까지만 동작을 수행한다.

 

2차원 리스트 컴프리헨션

a = ["a1","b1","c1"]
b = ["a2","b2","c2"]

[[a,b] for a,b in zip(a,b)]

## 결과
[['a1', 'a2'], ['b1', 'b2'], ['c1', 'c2']]

일반적으로는 이렇게 2차원 리스트 (2 dimensional list) 형태로 분류해서 데이터를 정리한다.

 

응용

math = [100, 90, 80]
eng = [85, 78, 92]
history = [90, 69, 88]

[sum(score) / 3 for score in zip(math,eng,history)]

## 결과
[91.66666666666667, 79.0, 86.66666666666667]

이렇게 각 과목별로 학생 번호순서대로 점수를 입력해놨다고 하자. zip을 이용해서 첫번째 학생의 각 과목 점수들만 불러올 수 있으므로 그것을 더하고 나눠서 평균 점수를 한번에 내주는 수식을 만들 수 있다. 파이썬 프로그래밍은 결국 배운 코드들을 직접, 많이 해서 익히고 그걸 센스있게 잘 응용해서 짜는게 실력인듯.

 

enumerate & zip

a = ["a1","b1","c1"]
b = ["a2","b2","c2"]

for i, values in enumerate(zip(a,b)):
    print(i,values)
    
## 결과
0 ('a1', 'a2')
1 ('b1', 'b2')
2 ('c1', 'c2')

마지막으로 enumerate 하고 zip을 같이 쓰는 방법이다. 먼저 zip으로 두 리스트의 같은 인덱스 원소들끼리 추출한 뒤 거기에 다시 enuemrate를 씌워서 인덱스 번호를 붙여준다. 그리고 i (인덱스 번호) values (원소값을 튜플 형태로 지정) 해서 출력을 해주었다.

 

values를 안쓰고 그냥 (a,b) 로 하던가 아니면 [a,b] 리스트 형태로 해주어도 상관없다. 원하는 자료형태로 만들어주면 된다.

 

 

파이써닉 코드 속도비교

리스트 컴프리헨션과 반복문으로 형성시의 속도 비교를 해보면 pythonic code를 사용했을 때 절반 가까이 더 빠르게 동작하는 것을 알 수 있다.

 

처음에는 새로운 코드를 배우는 것 같아서 어려운 느낌이었는데, 막상 요 간단한 문장만 이해하면 pythonic code가 오히려 사람이 이해하기가 훨씬 쉽고 편리한 것을 알 수 있다. 파이썬이 좀 재밌어지기 시작하는 부분이다.

728x90

블로그의 정보

TALI's MANDALA

금융투자의 만다라를 찾아서

활동하기