Câu hỏi Lặp lại từ điển bằng cách sử dụng 'for' loops


Tôi hơi bối rối bởi đoạn mã sau:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

Điều tôi không hiểu là key phần. Làm thế nào để Python nhận ra rằng nó chỉ cần đọc khóa từ từ điển? Là key một từ đặc biệt trong Python? Hay đơn giản chỉ là một biến?


2112
2017-07-20 22:27


gốc




Các câu trả lời:


key chỉ là một tên biến.

for key in d:

sẽ đơn giản lặp qua các phím trong từ điển, thay vì các khóa và giá trị. Để lặp qua cả khóa và giá trị, bạn có thể sử dụng như sau:

Đối với Python 2.x:

for key, value in d.iteritems():

Đối với Python 3.x:

for key, value in d.items():

Để tự kiểm tra, hãy thay đổi từ key đến poop.

Đối với Python 3.x, iteritems() đã được thay thế bằng cách đơn giản items(), trả về một chế độ xem giống như được hỗ trợ bởi dict, như iteritems() nhưng thậm chí còn tốt hơn. Điều này cũng có sẵn trong 2,7 như viewitems().

Các hoạt động items() sẽ hoạt động cho cả 2 và 3, nhưng trong 2 nó sẽ trả về danh sách từ điển (key, value) các cặp, sẽ không phản ánh những thay đổi đối với dict xảy ra sau items() gọi điện. Nếu bạn muốn hành vi 2.x trong 3.x, bạn có thể gọi list(d.items()).


3804
2017-07-20 22:29



Thêm lý do bị bỏ qua không truy cập vào giá trị như thế này: d [key] bên trong vòng lặp for khiến khóa được băm lại (để lấy giá trị). Khi từ điển lớn, băm thừa này sẽ thêm vào tổng thời gian. Điều này được thảo luận trong bài nói chuyện công nghệ của Raymond Hettinger youtube.com/watch?v=anrOzOapJ2E - Harisankar Krishna Swamy
trong Python 3.6 đã thay đổi thành d.items() - Decoded
Câu trả lời hay, và thiên tài thực sự nằm trong sự thay đổi key đến poop. Cảm ơn vì cái nhìn sâu sắc, @sberry! - Mike Williamson


Nó không phải là chìa khóa là một từ đặc biệt, nhưng các từ điển đó thực hiện giao thức lặp. Bạn có thể làm điều này trong lớp học của bạn, ví dụ: xem câu hỏi này để biết cách xây dựng trình vòng lặp lớp.

Trong trường hợp từ điển, nó được thực hiện ở cấp độ C. Các chi tiết có sẵn trong PEP 234. Đặc biệt, phần có tiêu đề "Từ điển Iterators":

  • Từ điển triển khai một khe tp_iter trả về hiệu quả   trình lặp mà lặp qua các khóa của từ điển. [...] Điều này   có nghĩa là chúng ta có thể viết

    for k in dict: ...
    

    tương đương, nhưng nhanh hơn nhiều

    for k in dict.keys(): ...
    

    miễn là hạn chế sửa đổi từ điển   (hoặc bởi vòng lặp hoặc bởi một chủ đề khác) không bị vi phạm.

  • Thêm phương thức vào từ điển trả về các loại khác nhau của   iterators một cách rõ ràng:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    Điều này có nghĩa rằng for x in dict là viết tắt của for x in dict.iterkeys().


325
2017-07-20 23:52



Trong python3 dict.iterkeys (), dict.itervalues ​​() và dict.iteritems () không còn được hỗ trợ nữa. Sử dụng dict.keys (), dict.values ​​() và dict.items () để thay thế. - Sadik


Lặp lại một dict lặp lại thông qua các khóa của nó không theo thứ tự cụ thể, như bạn có thể thấy ở đây:

Chỉnh sửa: (Đây là không còn là trường hợp trong Python3.6, nhưng lưu ý rằng nó không được bảo đảm hành vi chưa)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

Ví dụ của bạn, tốt hơn là nên sử dụng dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

Điều này cung cấp cho bạn một danh sách các bộ dữ liệu. Khi bạn lặp lại chúng như thế này, mỗi tuple được giải nén vào k và v tự động:

for k,v in d.items():
    print(k, 'corresponds to', v)

Sử dụng k và v dưới dạng tên biến khi lặp qua dict khá phổ biến nếu phần thân của vòng lặp chỉ là một vài dòng. Đối với các vòng lặp phức tạp hơn, bạn nên sử dụng nhiều tên mô tả hơn:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

Đó là một ý tưởng hay để có thói quen sử dụng các chuỗi định dạng:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

151
2017-07-21 01:27



Từ ghi chú phát hành Python 3.7: "Bản chất bảo quản thứ tự chèn của các đối tượng dict bây giờ là một phần chính thức của đặc tả ngôn ngữ Python." - Gregory Arenius


key chỉ đơn giản là một biến.

Dành cho Python2.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... hoặc tốt hơn,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Dành cho Python3.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

44
2017-07-20 23:49





Khi bạn lặp qua các từ điển bằng cách sử dụng for .. in ..-syntax, nó luôn lặp qua các khóa (các giá trị có thể truy cập bằng cách sử dụng dictionary[key]).

Để lặp qua các cặp khóa-giá trị, hãy sử dụng for k,v in s.iteritems().


39
2017-07-20 22:29



Lưu ý rằng đối với Python 3, nó là items() thay vì iteritems() - Andreas Fester


Đây là một thành ngữ lặp rất phổ biến. in là một toán tử. Khi nào nên sử dụng for key in dict và khi nào nó phải for key in dict.keys() xem Bài viết về thành ngữ của David Goodger.


20
2017-07-20 22:42



Khi tôi đọc những phần này về in, phần vận hành là nơi bạn kiểm tra sự tồn tại. Có lẽ xóa tốt hơn in is an operator thông tin. - Wolf


Bạn có thể sử dụng điều này:

for key,val in d.items():
    print key, 'is the key for ', val

9
2018-01-14 14:42



Bài cũ của nó một chút - Sadi
@Sadi Nó không còn đúng? - Basj


Tôi có một trường hợp sử dụng, nơi tôi phải lặp lại thông qua dict để có được cặp khóa, giá trị, cũng là chỉ số cho biết tôi đang ở đâu. Đây là cách tôi làm điều đó:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

Lưu ý rằng các dấu ngoặc đơn quanh khóa, giá trị là quan trọng, không có dấu ngoặc đơn, bạn sẽ nhận được một ValueError "không đủ giá trị để giải nén".


6
2018-05-25 13:42





Lặp lại từ điển bằng cách sử dụng 'for' loops

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

Python nhận ra rằng nó chỉ cần đọc khóa từ   từ điển? Là chìa khóa một từ đặc biệt trong Python? Hay đơn giản là   biến?

Nó không chỉ for vòng lặp. Từ quan trọng ở đây là "lặp lại".

Từ điển là ánh xạ khóa cho các giá trị:

d = {'x': 1, 'y': 2, 'z': 3} 

Bất cứ lúc nào chúng ta lặp lại nó, chúng ta lặp qua các phím. Tên biến key chỉ nhằm mục đích mô tả - và nó khá phù hợp với mục đích.

Điều này xảy ra trong một danh sách hiểu:

>>> [k for k in d]
['x', 'y', 'z']

Nó xảy ra khi chúng tôi chuyển từ điển vào danh sách (hoặc bất kỳ đối tượng loại bộ sưu tập nào khác):

>>> list(d)
['x', 'y', 'z']

Cách Python lặp lại là, trong một ngữ cảnh mà nó cần, nó gọi __iter__ phương thức của đối tượng (trong trường hợp này là từ điển) trả về một trình lặp (trong trường hợp này, một đối tượng keyiterator):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

Thay vào đó, chúng ta không nên sử dụng những phương thức đặc biệt này, sử dụng hàm dựng sẵn tương ứng để gọi nó, iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

Iterator có một __next__ nhưng chúng ta gọi nó bằng hàm dựng sẵn, next:

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Khi một iterator bị cạn kiệt, nó tăng StopIteration. Đây là cách Python biết để thoát khỏi for vòng lặp, hoặc một danh sách hiểu, hoặc một biểu thức máy phát điện, hoặc bất kỳ bối cảnh lặp khác. Khi một trình lặp tăng lên StopIteration nó sẽ luôn luôn nâng cao nó - nếu bạn muốn lặp lại, bạn cần một cái mới.

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

Quay trở lại dicts

Chúng tôi đã thấy các dicts lặp lại trong nhiều ngữ cảnh. Những gì chúng tôi đã thấy là bất cứ lúc nào chúng tôi lặp lại trên một dict, chúng tôi nhận được các phím. Quay lại ví dụ ban đầu:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

Nếu chúng ta thay đổi tên biến, chúng ta vẫn nhận được khóa. Hãy thử nó:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

Nếu chúng ta muốn lặp qua các giá trị, chúng ta cần sử dụng .values phương pháp của dicts, hoặc cho cả hai với nhau, .items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

Trong ví dụ được đưa ra, sẽ hiệu quả hơn khi lặp qua các mục như sau:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

Nhưng với mục đích học tập, ví dụ của câu hỏi là tốt.


4
2018-06-21 02:51





Bạn có thể kiểm tra việc triển khai CPython dicttype trên GitHub. Đây là chữ ký của phương thức thực hiện trình lặp dict:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c


3
2017-11-03 05:16