Tôi chỉ muốn thêm một số chi tiết vào Ignacio answer (điều này thật tuyệt) và tôi mất chút thời gian để hiểu và cho những người như tôi không nhận được nó (tôi có thể là người duy nhất không hiểu bởi vì tôi không thấy ai hỏi tôi không hiểu nhưng làm sao biết được :)):
lần đầu tiên tôi tự hỏi lát nào? lập chỉ mục từ điển không chấp nhận cắt?
nhưng đây là một câu hỏi ngu ngốc từ phần của tôi vì tôi quên rằng python là động (tôi ngu ngốc thế nào) vì vậy khi python biên dịch mã, python thời gian không biết foo
là từ điển hay danh sách vì thế nó chỉ cần đọc bất kỳ biểu hiện như foo này [ 'foo': 'bar'] như một lát, để biết rằng bạn chỉ có thể làm:
def f():
foo = {}
foo['bar':'foo']
và bằng cách sử dụng dis mô-đun bạn sẽ thấy rằng sự biểu hiện 'bar':'foo'
có được tự động chuyển đổi thành một lát:
dis.dis(f)
2 0 BUILD_MAP 0
3 STORE_FAST 0 (foo)
3 6 LOAD_FAST 0 (foo)
9 LOAD_CONST 1 ('bar')
12 LOAD_CONST 2 ('foo')
15 SLICE+3 <<<<<<<<<<<<<<<<<<<<<< HERE!!!!!!
16 POP_TOP
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
trong lần đầu tiên tôi thừa nhận tôi không nghĩ về điều này và tôi đã đi trực tiếp vào mã nguồn của python cố gắng hiểu tại sao, bởi vì __getitems__
của danh sách không giống như __getitem__
của một từ điển nhưng bây giờ tôi hiểu tại sao vì nếu nó một lát và lát là unhashable nó nên nâng unhashable type
, vì vậy đây là mã của từ điển __getitem__
:
static PyObject *
dict_subscript(PyDictObject *mp, register PyObject *key)
{
PyObject *v;
long hash;
PyDictEntry *ep;
assert(mp->ma_table != NULL);
if (!PyString_CheckExact(key) || // if check it's not a string
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key); // check if key (sliceobject) is hashable which is false
if (hash == -1)
return NULL;
}
....
Hy vọng điều này có thể giúp một số người như tôi để hiểu được phản ứng tuyệt vời của Ignacio, và xin lỗi nếu tôi chỉ lặp lại câu trả lời của Ignacio :)
Tôi phải thừa nhận, điều đó không xảy ra với tôi. +1 – delnan