본문 바로가기

언어/Python

[Python] PS하면서 내가 보려고 만든 조금이라도 헷갈렸던 문법들.

이번 포스팅은 Python을 공부하고 나서 ps문제를 계속해서 풀어보면서 문법부분에서 아주 조금이라도 헷갈렸던 부분을 전부 적어보려고 합니다.

 

1. 리스트 내림차순 올림차순 정렬.

list가 있을때

list.sort()로 올림차순 , ()안에 reverse = True 를 작성시 내림차순으로 정렬된다. 이때 시간복잡도는 NlogN.

힙소트와 머지소트와 비견될 정도이고 사용법도 시간을 많이 줄여주니 생각보다 좋은것같다. 그냥 바로 어떤배열을 정렬 하고 싶다면, sorted([9,1,8,5]) 요래 하면된다.

 

 

2. sys.stdin.readline()

사실 첫줄에는 input으로 입력받아도 무관하다 한다. 하지만 반복문에서 입력받을시에는 시간초과를 고려해 위의 문법을 사용해야한다.

이렇게 받은 것들은 모두 문자열로 저장이된다.

다만 한개의 정수만을 입력받을때 rstrip()을 꼭 적어줘야 개행문자까지 인식하는 불상사를 막는다.

여러개를 입력받을시, 

1. a,b,c = map(int,sys.stdin.readline().split())

2. data = list(map(int,sys.stdin.readline().split()))

이렇게 받는다. 1 번은 a b c각각에 입력받은 순서로 띄워쓰기를 기준으로 저장.

2번은 data에 list형태로 저장.

 

이차원 배열형태로 저장받고 싶을시에는,

import sys

data = []

n = int(sys.stdin.readline())

for i in range(n): data.append(list(map(int,sys.stdin.readline().split())))

 

3. for i in range() 

사실 for문은 아주 기본이어서 아무생각없이 막쓰고 있었는데 그러다보니 한줄정도 더 적게되는 비효율적인 낭비가 발생하곤 했다. range는 0부터 지정숫자까지 0 , 1 , 2, 3, 4 . . . 를 만들고, 이를 i에 넣는 것이다.

이때 만약 list가있어서 [ 10, 5, 4, 2, 6 ] 과 같이 있다면 for i in (임의의)list 를 한다면 더욱 짧고 편하게 전개될수 있는 상황들이 꽤나 있었다.

이때, i없이 _ 만 넣고 range로 돌린다면, 단순하게 반복만 된다.

 

4. 반복문으로 전개되는 긴 자리수의 숫자들중 3이포함될시 rst += 1 을시키려했다.

이때 나는 

for i in range(N+1) :
for j in range(60):
for k in range(60):
if '3' in str(i) or str(j) or str(k) :
rst+=1

 

이와 같이 무매몽지하게 작성하였다. 이렇게 하니 5를 입력하니 18000이 나왔는데, 

 

for i in range(N+1) :
for j in range(60):
for k in range(60):
if '3' in str(i) + str(j) + str(k) :
rst+=1

 

이와 같이 하니 정수들이 전부 합쳐져 3을 찾게 되었다.

 

 

5. 리스트끼리 더하기.

list1 = [1,2,3]

list2 = [5,6,7]

이 있어서 list1 + list2 하면은 [1,2,3,4,5,6,7]이 나온다.

하나씩 더하고 싶다면, 여러가지 방법이 있는데 그중 나는 

import operator를 한 후 ,

map(operator.add,list1,list2)를 하는 방법을 사용했다.

그리고, 만약 list1 = [1,2,3]

list2 = [ [3,4,5], [6,7,8], [9,10,10] . . . ] 이렇게 된다면, 

for i in move:
ans = list(map(operator.add,i,knight))

이런식으로 list형변환으로 map함수를 사용한다.

 

★ 하지만 이는 ans의 원형을 건드는게 아니기때문에 for문 루프일때 if문등을 사용해 작업을 처리해주어야 한다.

 

6. in codeup 2010

 

반올림함수 : 내장함수. import 필요없다. round(반올림할 숫자, 소수점아래 자리수)

내림함수 : import math 후에, math.floor or 올림시 math.ceil 인자는 하나만 주어야함.

pow함수 : pow(2,3) --> 2의 3승. 즉,  ( 숫자, 지수 )

 

 

7 . for i in list 와 for i in list[:] 사용시 차이점.

 

프로그래머스 문제를 풀다가 문득 list와 list[:] 의 차이점을 발견할 수 있었다.

그냥 list라고 작성시, for 문으로 remove를 돌리던중, 만약 remove로써 list가 전부 삭제되었을시, 더이상 for문이 진행되지 않음을 디버깅으로써 확인할 수 있었다.

하지만, list[:]로 했을때 for문으로 remove를 돌린다면, list가 전부 삭제 되었을시, [:]라고 표기했기때문에 for문이 더 진행하고자 하다가 에러가 뜨는 모습을 확인할 수 있었다. 

결론, list는 원본을 자체를 반영, list[:] 원본을 지워지더라도 모든요소를 꼭 반영.

 

 

8 . 

del : 인덱스로 삭제

remove( ) 함수 : 값으로 삭제

 

9. 리스트.sort()와 sorted(리스트)의 가장 큰 차이는
리스트.sort() 는 본체의 리스트를 정렬해서 변환하는 것이고,
sorted(리스트) 는 본체 리스트는 내버려두고, 정렬한 새로운 리스트를 반환하는 것입니다.

 

 

10. 

리스트 합치기 math = [[1,2,3,4,5],[1,3,2,4,1],[1,2,3,5,4]]일때, math[0].extend(math[0] * 2) 시, [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]math[0].extend(math[0][:4]) 시 , [1,2,3,4,5,1,2,3]

 

 

11. 

dict의 활용

<오픈채팅방> 문제 中

 

dict활용을 제대로 못한 나의 코드:

 

   # 배열의 첫번째 단어가 change라면 ,
    for k in range(len(temp)):
        if temp[k][0] == 'Change' :
            #미리 선언해둔 change에 temp의 'change enter leave' 제외하고 넣기.
            change.extend(temp[k][1:])
            # leave의 경우 except처리.
            try :
                for answers in temp:
                    # 배열 앞순서부터 id로 찾아, change로 바꾸기.
                    if change[0] in answers :
                        answers[2] = change[1]
            except :
                continue
    # ENTER의 경우,
    # tmp에 temp deepcopy
    tmp = copy.deepcopy(temp)
    for j in range(len(temp)):
        if temp[j][0] == 'Enter' :
            for d in range(len(temp)):
                try :
                    if tmp[d][1] == tmp[j][1] :
                        temp[d][2] = tmp[j][2]
                except :
                    continue

for문이 덕지덕지 붙어있다. 

의도는 , 아이디와 닉네임을 따로 저장해서 change와 enter가 나오면 따로 tmp를 deepcopy해두어 처음부터 끝까지 돌리면 마지막에 change나 enter가 되더라도 바뀌겠지 하며 작성하였다.

그러나 best는,  dict로써 id를 key로 저장해두고 value를 닉네임으로 change나 enter를 넣으면 계속해서 바꾸면 되는 것인데 이때 dict를 활용하지 않았다.

 

그래서 개선한 코드.

    for i in range(len(record)):
        data = record[i].split()
        if (data[0] == 'Enter') or (data[0] == 'Leave'): log.append((data[0], data[1]))
        if (data[0] == 'Enter') or (data[0] == 'Change'): dic[data[1]] = data[2]

data[1]에 계속해서 key data[2] 가 enter나 change일때 들어감.

리스트로 저장시 오류가뜨는데 dict로 저장할시 계속해서 값이 바뀐다..!!

 

12. map함수로 두 리스트 간 곱하기.!

 for j in arr1:
        temp=[]
        for i in range(len(second_temp)):
            temp.append(sum(list(map(lambda x,y:x*y,j,second_temp[i]))))
        answer.append(temp)

 

더욱 간단한 예제.

list1 = [2,4,5,3,5,4]
list2 = [4,1,2,9,7,5]
product = list(map(lambda x,y: x*y ,list1,list2))
print(product)

출력 : [8, 4, 10, 27, 35, 20]

 

list1 = [[2,4,5],[3,5,4]]
list2 = [[4,1,2],[9,7,5]]
product = [[0]*3]*2 

for x in range(len(list1)):
    product[x] = list(map(lambda a,b: a*b ,list1[x],list2[x]))

print(product)

출력 : [[8, 4, 10], [27, 35, 20]]

 

13.

 

 

logs = ["a1 9 2 3 1"] 와 같이 주어져 있을때 띄워쓰기 단위로 일을 하고싶다.

=>print(logs[0].split(' ')[:]) split후에 인덱스 지정가능.

 

활용 예시 :

logs = ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo","a2 act car"]

#print(sorted(logs,key=lambda x : x[0:].split(' ')[1]))

def solution(logs : list) -> list:
    temp_alpha = list()
    temp_num = list()

    for i in logs[:]:
        if i.split(' ')[1].isalpha():
            temp_alpha.append(i)
            logs.remove(i)
        elif i.split(' ')[1].isdigit():
            temp_num.append(i)

    temp_alpha = sorted(temp_alpha,key=lambda x : (x[0:].split(' ')[1:],x[0:].split(' ')[0]))
    temp_alpha.extend(temp_num)
    return temp_alpha


print(solution(logs))

그리고 람다사용시, 1개만이 아닌, 2개의 키를 람다 표현식으로 나타낼수 있다. 사용방법은 람다x : 후에 괄호 넣기.

 

 

- 계속해서 추가 할 예정!