Unpack trong python
TIL
720
White

Chiến Kira viết ngày 09/04/2019

Unpack trong python

Link bài viết gốc ở blog của mình: chienkira.github.io/blog/thủ thuật unpack trong python


Ký tự * ngoài là toán tử multiplication (phép nhân) và string replication ra, trong Python nó còn có một tác dụng khác khá xịn xò - unpack (một số người còn gọi là splat).

Ký hiệu *

Unpack chỉ có thể áp dụng lên một object loại iterable, để áp dụng việc cần làm là đặt ký hiệu * lên liền ngay trước object đó.

Ví dụ:

Dùng trực tiếp với biến: *list_variable

Dùng với biểu thức: *[i*2 for i in some_array]

Phép unpack với ký hiệu * sẽ sinh ra "các phần tử", được tách ra từ iterable object ban đầu.

Ví dụ như

  • Nếu áp dụng lên một object kiểu list, ta sẽ nhận được các phần tử có trong list đó.
  • Nếu áp dụng lên một object kiểu dictionary, ta sẽ nhận được các keys (chỉ key thôi, không có value) có trong dictionary đó.

Cùng xem qua đoạn code ví dụ sau để hình dung rõ hơn công dụng của unpack.

# Method test nhận vào 3 params
def test(a, b, c):
    print("a =", a)
    print("b =", b)
    print("c =", c)

# object này có 3 phần tử
list = [1, 2, 3]

test(list)
# Sẽ bị lỗi TypeError: test() missing 2 required positional arguments: 'b' and 'c'

test(*list)
# a = 1
# b = 2
# c = 3

Unpack đã giúp tách độc lập các phần từ có trong object list ra, do đó method test nhận vào được đúng 3 params a, b và c tương ứng với 3 phần tử trong object list.

Đến đây thì nếu liên tưởng chút, ta sẽ thấy cách viết quen thuộc sau hiện lên ở trong đầu.

def my_method(*args):
    #do something

Vâng chính là nó rồi đó ạ, *args quen thuộc ở đây bản chất là một trick sử dụng phép unpack. Unpack biến args tương đương với chuỗi các param truyền vào method. Vì thế mà trong method khi truy cập biến args, ta nhận được list chứa toàn bộ các params. Mình hay gọi cái này là phép nghịch đảo của unpack cho dễ hiểu.

Nhắc đến *args rồi thì lại phải nhắc đến họ hàng của nó là **kwargs :)) Vậy thì ta chuyển sang mục tiếp theo Ký hiệu `` thôi!

Ký hiệu **

Unpack khi sử dụng ký hiệu ** có hiệu quả khác với khi sử dụng ký hiệu * ở chỗ, nó chuyên tách object kiểu dictionary thành các cặp key-value độc lập.

Nó giúp việc truyền một dict vào một method mà chỉ nhận keyword params dễ dàng hơn rất nhiều.

Đoạn code demo ví dụ sau sẽ dễ hiểu hơn mọi giải thích dài dòng :smiley:

# Method test nhận vào 3 keyword params
def test(a=a, b=b, c=c):
    print("a =", a)
    print("b =", b)
    print("c =", c)

# dict này có 3 key, thứ tự có thể không cần giống thứ tự keyword trong method test
dict = {"a": 11, "c": 22, "b": 33}

test(dict)
# Sẽ bị lỗi TypeError: test() missing 2 required positional arguments: 'b' and 'c'

test(**dict)
# a = 11
# b = 22
# c = 33

Unpack trong các ngôn ngữ khác

Javascript ES 6 cũng đã hỗ trợ phép unpack nhưng với tên gọi khác là spread, và sử dụng ký hiệu ....

const numbers = [5, 6, 8, 9, 11, 999]
Math.max(...numbers)

Còn trong ruby thì gọi là phép splat, về mặt ký hiệu và cách dùng nó giống như python.

people = ["Rudy", "Sarah", "Thomas"]
say *people

Sử dụng lâu rồi nhưng không hiểu bản chất bên dưới của nhiều đoạn code là phép unpack này, thật là xấu hổ quá. Bài này chủ yếu mang tính sắp xếp lại kiến thức của bản thân. Nếu bạn nào trót vào đọc và thấy chả có khỉ gì thì rất xin lỗi ạ!


Link bài viết gốc ở blog của mình: chienkira.github.io/blog/thủ thuật unpack trong python

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Chiến Kira

7 bài viết.
25 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
15 1
Lập trình viên không sớm thì muộn cũng sẽ yêu cái máy tính không khác gì yêu vợ. Rồi ngày qua ngày tiếp xúc với cửa sổ dòng lệnh, mắt lập trình viê...
Chiến Kira viết 5 tháng trước
15 1
White
12 2
Blue green deployment là cái khỉ ho gì? Nó có gì hay và có "ngon" không? Nếu bạn đang có câu hỏi tương tự trong đầu thì hãy thử đọc hết bài viết n...
Chiến Kira viết 5 tháng trước
12 2
White
3 2
Bài viết gốc ở blog của mình: https://chienkira.github.io/blog/posts/%C3%A1pd%E1%BB%A5ngcircleci/ Lúc đầu trang blog này mình định deploy bằng tay...
Chiến Kira viết 5 tháng trước
3 2
Bài viết liên quan
White
0 4
fCC: Technical Documentation Page note So I have finished the HTML part of this exercise and I want to come here to lament about the lengthy HTML ...
HungHayHo viết 1 năm trước
0 4
White
2 0
I used Spring boot, Hibernate few times back then at University, I'v started using it again recently. In this (Link), I want to check how Spring J...
Rey viết 7 tháng trước
2 0
White
22 1
Toán tử XOR có tính chất: + A XOR A = 0 + 0 XOR A = A Với tính chất này, có thể cài đặt bài toán sau với độ phức tạp O(N) về runtime, và với O(1)...
kiennt viết gần 3 năm trước
22 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
7 bài viết.
25 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!