本文最終將清楚了解:
得知了 list 與 tuple 的 methods 之差異,例如 list 可以 sort 排序, 而 tuple 就不能 sort 排序;
以及兩者的特性:
List其特性有:
List is a collection which is ordered and changeable. Allows duplicate members.
且tuple因其特性有:
Tuple is a collection which is ordered and unchangeable. Allows duplicate members.
是ordered順序性與unchangeable(不可改變)的特性。
內文開始:
使用Python語法開發的工程師,應該都知道list 與 tuple這兩種的差異性。也應熟知它們之間可用的methods,list是比較多,tuple是比較少。
List其特性有:
List is a collection which is ordered and changeable. Allows duplicate members.
且tuple因其特性有:
Tuple is a collection which is ordered and unchangeable. Allows duplicate members.
是ordered順序性與unchangeable(不可改變)的特性。為何呢??
當你是資深Python工程師,我個人觀點是要很深入了解,Python其底層源碼是什麼? 才會讓 List 與 tuple 兩種有些差異性。 [ 註: 或者是從事 Python 程式設計講師 也是要非常熟源碼 ]
先剖析 List 是 ordered and changeable;tuple是 ordered and unchangeable。
觀察Python 源碼的 listobject.h 與 tupleobject.h,
在 listobject.h 有 PyListObject 的宣告:
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
在 tupleobject.h有 PyTupleObject 的宣告:
typedef struct {
PyObject_VAR_HEAD
PyObject *ob_item[1];
} PyTupleObject;
兩者第一個 struct member是 PyObject_VAR_HEAD,這定義在 object.h,有關之程式碼如下:
#define PyObject_VAR_HEAD PyVarObject ob_base;
PyObject_VAR_HEAD是個巨集,其marco defination是 PyVarObject ob_base;
再來 PyVarObject 的定義如下:
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
PyVarObject第一個member是PyObject,其定義如下:
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
PyObject第一個member是 _PyObject_HEAD_EXTRA ,其定義如下:
再分析一下源碼的 _PyObject_HEAD_EXTRA,
#ifdef Py_TRACE_REFS
/* Define pointers to support a doubly-linked list of all live heap objects. */
#define _PyObject_HEAD_EXTRA \
struct _object *_ob_next; \
struct _object *_ob_prev;
#define _PyObject_EXTRA_INIT 0, 0,
#else
#define _PyObject_HEAD_EXTRA
#define _PyObject_EXTRA_INIT
#endif
這段是如果定義了 Py_TRACE_REFS 則 Objects 會變成是一個雙向列表, 但是在release版本下沒有定義 Py_TRACE_REFS , 因此這個 MARCO 可以忽略.
最終的 list 與 tuple 之結構型態的 member 呈現分別是:
在 listobject.h 有 PyListObject 的宣告:
typedef struct {
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
Py_ssize_t ob_size;
PyObject **ob_item; //此處PyObject宣告了List的 ob_item
Py_ssize_t allocated;
} PyListObject;
在 tupleobject.h有 PyTupleObject 的宣告:
typedef struct {
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
Py_ssize_t ob_size;
PyObject *ob_item[1]; //此處PyObject宣告了 tuple 的 ob_item
} PyTupleObject;
在最終的 list 與 tuple 之結構型態知道,list 是以 PyObject **ob_item; 來處理其 item data;
而 tuple 是以 PyObject *ob_item[1]; 來處理其 item data。
因其型態特性不同,致在其對應的PyTypeObject也不同。
list 的 PyTypeObject 源碼在 listobject.c,程式如下:
PyTypeObject PyList_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"list",
sizeof(PyListObject),
0,
(destructor)list_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)list_repr, /* tp_repr */
0, /* tp_as_number */
&list_as_sequence, /* tp_as_sequence */
&list_as_mapping, /* tp_as_mapping */
PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */
list___init____doc__, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */
(inquiry)_list_clear, /* tp_clear */
list_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
list_iter, /* tp_iter */
0, /* tp_iternext */
list_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)list___init__, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
tuple 的 PyTypeObject 源碼在 tupleobject.c,程式如下:
PyTypeObject PyTuple_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"tuple",
sizeof(PyTupleObject) - sizeof(PyObject *),
sizeof(PyObject *),
(destructor)tupledealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)tuplerepr, /* tp_repr */
0, /* tp_as_number */
&tuple_as_sequence, /* tp_as_sequence */
&tuple_as_mapping, /* tp_as_mapping */
(hashfunc)tuplehash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
tuple_new__doc__, /* tp_doc */
(traverseproc)tupletraverse, /* tp_traverse */
0, /* tp_clear */
tuplerichcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
tuple_iter, /* tp_iter */
0, /* tp_iternext */
tuple_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
tuple_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
我們現將注意力放在其 methods 操作方法:
list 的 methods 操作方法,源碼如下:
static PyMethodDef list_methods[] = {
{"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"},
LIST___REVERSED___METHODDEF
LIST___SIZEOF___METHODDEF
LIST_CLEAR_METHODDEF
LIST_COPY_METHODDEF
LIST_APPEND_METHODDEF
LIST_INSERT_METHODDEF
LIST_EXTEND_METHODDEF
LIST_POP_METHODDEF
LIST_REMOVE_METHODDEF
LIST_INDEX_METHODDEF
LIST_COUNT_METHODDEF
LIST_REVERSE_METHODDEF
LIST_SORT_METHODDEF
{NULL, NULL} /* sentinel */
};
而 tuple 的 methods 操作方法,源碼如下:
static PyMethodDef tuple_methods[] = {
TUPLE___GETNEWARGS___METHODDEF
TUPLE_INDEX_METHODDEF
TUPLE_COUNT_METHODDEF
{NULL, NULL} /* sentinel */
};
到此得知了 list 與 tuple 的 methods 之差異,例如 list 可以 sort 排序, 而 tuple 就不能 sort 排序;
以及兩者的特性:
List其特性有:
List is a collection which is ordered and changeable. Allows duplicate members.
且tuple因其特性有:
Tuple is a collection which is ordered and unchangeable. Allows duplicate members.
是ordered順序性與unchangeable(不可改變)的特性。
訂閱:
張貼留言 (Atom)
FPGA Verilog 的學習經驗,提供給要入門的新手
今天簡單說說 FPGA Verilog 的學習經驗,提供給要入門的新手: 1.對自己寫的FPGA Verilog程式,所生成的數位電路要心中有數。 這一點個人認為很重要,就正如寫 C語言,心中要能生成對應的組合語言一樣,我是這樣要求自己的。 雖然 FPGA Verilog語言...
-
今天簡單說說 FPGA Verilog 的學習經驗,提供給要入門的新手: 1.對自己寫的FPGA Verilog程式,所生成的數位電路要心中有數。 這一點個人認為很重要,就正如寫 C語言,心中要能生成對應的組合語言一樣,我是這樣要求自己的。 雖然 FPGA Verilog語言...
-
這影片是紀錄 【Python +OpenCV】Python 3 程式設計最佳入門到進階應用實戰工程師培訓班:基礎至進階語法+影像處理與辨識(OpenCV) 課程的DEMO部分,請參考相關網頁: 先決條件是必須先安裝好相關的程式: Python、Opencv。。。。。。 ...
-
使用Arduino完成 RFID 結合Keypad鍵,可控制門鎖(或開關)之應用系統 此範例參考自 Arduino 官網的RFID範例並改寫[註]。官網的周邊與我的有差異,所以需自行修改程式碼以符合我手上的硬體周邊。 此範例硬體系統有: 1. Arduino U...
沒有留言:
張貼留言