[Python] lambda > filter

채록·2021년 4월 12일
0

Python & Django

목록 보기
30/34
post-thumbnail

중복값을 찾아 조건별로 다른 로직을 처리하고싶을때 for loopsif문이 과하게 많이 사용되었다.
대충 이정도?

변수사용량도 너무 많아서 의미있는 변수명이 아니라 급한대로 aa, jj, cccc등등 이 사용되었다.


위 코드는 로그인 유저의 주문내역list를 반환하는 데이터에 관한 로직으로 두개의 SQL문으로 부터 원하는 형태로 데이터를 가공하려다 보니 이런식의 코드가 짜여졌다. 심지어 미완성




1. 처리 과정



1. Dao


위 정보를 가져오기 위해 구현되는 Dao는 두가지이다.
1. 로그인 유저가 결제한 주문내역의 주문번호, 주문시간 가져오는 Dao
2. 위의 주문번호를 FK로 갖고있는 상품옵션 Dao

각각 Dao의 SQL문으로부터 가져오는 정보는아래와 같다.

1. 주문번호 Dao

  • 주문번호의 pk(id)
  • 주문번호 생성 시간
  • 주문번호의 외부용고유번호

2. 상품옵션 Dao

  • 주문번호의 외부용고유번호
  • 카트의 pk(id)
  • 카트에 담긴 상품의 최종 금액
  • 카트에 담긴 상품의 수량
  • 카트의 외부용고유번호
  • 카트에 담긴 상품의 상태(status)
  • 카트에 담은 유저의 id
  • 상품의 pk(id)
  • 상품 이름
  • 상품의 색상옵션
  • 상품의 사이즈옵션
  • 상품의 이름
  • 상품의 할인률
  • 상품의 할인된 가격
  • 상품의 대표 이미지
  • 판매자의 pk(id)
  • 판매자의 한국 브랜드명


2. data 가져오기

1. 주문번호 가져오기

먼저 1번 Dao를 통해 로그인유저의 결제완료상태인 주문번호를 가져온다.
그리고 그 번호들을 list에 담는다.

order_header = mypage_dao.mypage_order_header_dao(connection, user, page_condition)
order_id = [o['id'] for o in order_header]

2. 거른 주문번호 활용해 정보 가져오기

이 list를 2번 Dao에 함께 넘겨주어 list에 해당하는 주문번호의 외부고유번호를 지닌 상품 옵션에 대한 정보만 거른다.

# 로그인 유저의 주문 목록 반환
order_header = mypage_dao.mypage_order_header_dao(connection, user, page_condition)
order_id = [o['id'] for o in order_header]
        
# 해당되는 주문목록에 속하는 구매 목록 반환
order_cart = mypage_dao.mypage_order_cart_dao(connection, user, page_condition, order_id)



3. 형태 가공하기

두가지 조건으로 grouping 해주어야한다.

  1. 주문번호로 grouping
  2. 한개의 주문번호 내에서 같은 브랜드명으로 grouping

1. 주문번호로 grouping

먼저 주문번호로 grouping 해주기 위해 Dictionary 형태를 만들어 준다.

# 해당되는 주문목록에 속하는 구매 목록 반환
order_cart = mypage_dao.mypage_order_cart_dao(connection, user, page_condition, order_id)
order_list = [{
    "orderId": order_head['id'],
    "orderNumber": order_head['orderNumber'],
    "orderTime": order_head['created_at'],
    "product": []
} for order_head in order_header]

2. 상품명으로 grouping _ 1 : 조건에 맞는 list 생성

위의 두번째 Dao를 통해 order_cart라는 변수에는 주문번호에 해당되는 상품옵션들이 list 형태로 담겨있다.
for loops를 통해 상품옵션 하나로부터 외부용주문번호상품이 판매되는 브랜드를 가져오고, 이를 조건으로 중복값에 대한 여부를 확인한다.

이때 사용된 것이 lambda의 filter기능이다.

for cart in order_cart:
    order_num = cart['orderNumber']
    brand = cart['brand']
    order = list(filter(lambda d: d['orderNumber'] == order_num,  order_list))[0]
    option_brand = list(filter(lambda d: d['brand'] == brand,  order['product']))
  1. for loops을 도는 상품옵션 한개값이 1번 Dao를 통해 반환된 주문번호와 같다면 해당되는 order_list의 list한개 값을 order라는 변수로 지정한다.
  2. for loops을 도는 상품옵션의 브랜드명이 order['product']에 있을 경우와 없을 경우를 처리한다.

3. 상품명으로 grouping _ 2 : 있을 경우 / 없을 경우

for cart in order_cart:
    order_num = cart['orderNumber']
    brand = cart['brand']
    order = list(filter(lambda d: d['orderNumber'] == order_num,  order_list))[0]
    option_brand = list(filter(lambda d: d['brand'] == brand,  order['product']))
    if not option_brand:
        option_brand = {'brand': brand, 'option':[]}
        order['product'].append(option_brand)
    else:
        option_brand = option_brand[0]
    option_brand['option'].append(cart)

1) 없을 경우 (if not)

  • 새로 option_brand라는 Dictionary 형태의 변수를 만들고, brand에는 lambda식을 사용했던 조건인 brand명을, option이라는 key값은 value가 list 형식임을 지정한다.
  • 그리고 나서 order의 option이라는 key값에 option_brand를 append한다.

=> order의 product라는 key값에 같은 주문번호에 해당하는 상품옵션에 대한 내용이 담기게 된다.

2) 있을 경우 (else)

  • 이미 brand명에 대한 것이 생성되어 있으므로 새로운 변수생성 없이 option_brand = option_brand[0]을 선언해준다.

3) 한번의 for loops 종료

  • Dictionary 형태의 option_brand의 option이라는 key값에 cart 를 append 한다.




4. 최종 데이터 반환 형태

{
    "message": "SUCCESS",
    "result": {
        "data": [
            {
                "orderNumber": "10001",
                "orderTime": "Sat, 03 Apr 2021 00:00:00 GMT",
                "product": [
                    {
                        "brand": "말랑말랑",
                        "option": [
                            {
                                "cartId": 1,
                                "cartOrderId": 1,
                                "productColor": "레드",
                                "productName": "따듯한 아우터",
                                "productSize": "Small",
                                "quantity": 2,
                                "sellerId": 1
                            }
                        ]
                    },
                    {
                        "brand": "우나나나",
                        "option": [
                            {
                                "cartId": 3,
                                "cartOrderId": 1,
                                "productColor": "레드",
                                "productName": "차가운 아우터",
                                "productSize": "Large",
                                "quantity": 1,
                                "sellerId": 6
                            },
                            {
                                "cartId": 2,
                                "cartOrderId": 1,
                                "productColor": "레드",
                                "productName": "차가운 아우터",
                                "productSize": "Medium",
                                "quantity": 1,
                                "sellerId": 6
                            }
                        ]
                    }
                ]
            },
            {
                "orderNumber": "10002",
                "orderTime": "Mon, 05 Apr 2021 00:00:00 GMT",
                "product": [
                    {
                        "brand": "우나나나",
                        "option": [
                            {
                                "cartId": 4,
                                "cartOrderId": 2,
                                "productColor": "레드",
                                "productName": "차가운 아우터",
                                "productSize": "Medium",
                                "quantity": 1,
                                "sellerId": 6
                            }
                        ]
                    }
                ]
            }
        ]
    }
}
profile
🍎 🍊 🍋 🍏 🍇

0개의 댓글