Làm thế nào để lập chỉ mục vào từ điển?


97

Tôi có một Từ điển bên dưới:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

Làm cách nào để lập chỉ mục mục nhập đầu tiên trong từ điển?

colors[0]sẽ trả về một KeyErrorvì những lý do rõ ràng.


4
"Đầu tiên" nghĩa là gì? Từ điển không có thứ tự.
S.Lott

2
Từ điển hiện đang chèn lệnh từ Python 3.7 Hãy kiểm tra này: stackoverflow.com/questions/39980323/...
Nikita Alkhovik


1
@ S.Lott Tôi cá là anh ấy sẽ không hỏi nếu biết chúng không có thứ tự :).
user7778287 21/07/19

Câu trả lời:


112

Các từ điển không có thứ tự trong các phiên bản Python cho đến và bao gồm cả Python 3.6. Nếu bạn không quan tâm đến thứ tự của các mục nhập và vẫn muốn truy cập các khóa hoặc giá trị theo chỉ mục, bạn có thể sử dụng d.keys()[i]d.values()[i]hoặc d.items()[i]. (Lưu ý rằng các phương pháp này tạo danh sách tất cả các khóa, giá trị hoặc mục trong Python 2.x. Vì vậy, nếu bạn cần chúng nhiều hơn thì một lần, hãy lưu trữ danh sách trong một biến để cải thiện hiệu suất.)

Nếu bạn quan tâm đến thứ tự của các mục nhập, bắt đầu với Python 2.7, bạn có thể sử dụng collections.OrderedDict. Hoặc sử dụng danh sách các cặp

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

nếu bạn không cần truy cập bằng chìa khóa. (Nhân tiện, tại sao các số của bạn lại là chuỗi?)

Trong Python 3.7, các từ điển thông thường được sắp xếp theo thứ tự, vì vậy bạn không cần phải sử dụng OrderedDictnữa (nhưng bạn vẫn có thể - về cơ bản nó cùng một loại). Việc triển khai CPython của Python 3.6 đã bao gồm thay đổi đó, nhưng vì nó không phải là một phần của đặc tả ngôn ngữ, bạn không thể dựa vào nó trong Python 3.6.


2
Trong Python 2, sử dụng d.iterkeys().next()thay vì d.keys()[0]kiểm tra một trong các khóa mà không cần xóa nó. Nếu từ điển lớn, nó sẽ tạo ra sự khác biệt lớn về mặt hiệu suất. Tương tự đối với các giá trị và mục. Trong Python 2.7 bạn cũng có thể sử dụng dict đối tượng xem
simleo

44
Trong Python 3, các lệnh gọi này trả về một dạng xem, thay vì một danh sách thực tế, vì vậy bạn nên bọc chúng trong một lệnh gọi tới list () nếu không bạn sẽ thấy: "Đối tượng TypeError: 'dict_values' không hỗ trợ lập chỉ mục". Xem câu hỏi SO này: stackoverflow.com/questions/17431638/…
stifin

3
Chỉ là một sự điều chỉnh: bạn không thể lập chỉ mục các mục (), ít nhất là không phải trong Python 3.
John Strong

1
Câu trả lời này đã lỗi thời cho python 3.6+, vui lòng xem câu trả lời của @Pasha bên dưới.
hans

1
@hans Câu trả lời này đã lỗi thời đối với Python 3.7, nhưng không phải đối với Python 3.6, vì bản chất bảo tồn thứ tự của từ điển là chi tiết triển khai của việc triển khai CPython của phiên bản Python đó, không phải là một phần chính thức của ngôn ngữ. Tôi sẽ cập nhật câu trả lời này cho phù hợp.
Sven Marnach

112

Nếu ai đó vẫn đang xem câu hỏi này, câu trả lời hiện được chấp nhận hiện đã lỗi thời:

Kể từ Python 3.7 *, các từ điển được bảo toàn trật tự , nên giờ đây chúng hoạt động chính xác như collections.OrderedDicttrước đây. Thật không may, vẫn không có phương pháp chuyên dụng nào để lập chỉ mục vào keys()/ values()của từ điển, vì vậy việc lấy khóa / giá trị đầu tiên trong từ điển có thể được thực hiện như

first_key = list(colors)[0]
first_val = list(colors.values())[0]

hoặc cách khác (điều này tránh tạo chế độ xem khóa thành danh sách):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

Nếu bạn cần nkhóa -th, thì tương tự

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(* CPython 3.6 đã bao gồm các phần có thứ tự, nhưng đây chỉ là chi tiết triển khai. Đặc tả ngôn ngữ bao gồm các phần có thứ tự từ 3.7 trở đi.)


Vui lòng cung cấp liên kết đến tài liệu tương ứng?
Amir Afianian

3

Giải quyết một yếu tố của từ điển giống như ngồi trên con lừa và tận hưởng chuyến đi.

Theo quy tắc của Python DICTIONARY là không có thứ tự

Nếu đó là

dic = {1: "a", 2: "aa", 3: "aaa"}

Bây giờ giả sử nếu tôi thích dic[10] = "b", thì nó sẽ không thêm như thế này luôn

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

Nó có thể giống như

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Hoặc là

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Hoặc là

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Hoặc bất kỳ sự kết hợp nào như vậy.

Vì vậy, quy tắc ngón tay cái là DICTIONARYvô trật tự !


điều này rất đơn giản ... Tôi thích nó!
Alex Liu 33214

2

Nếu bạn cần một từ điển có thứ tự, bạn có thể sử dụng odict .


odict thấy không hỗ trợ lập chỉ mục thành các khóa (), giá trị () hoặc mục ().
Konstantin

2

thực sự tôi đã tìm thấy một giải pháp mới thực sự giúp ích cho tôi, Nếu bạn đặc biệt quan tâm đến chỉ mục của một giá trị nhất định trong danh sách hoặc tập dữ liệu, bạn có thể chỉ cần đặt giá trị của từ điển thành Chỉ mục đó !:

Cứ xem đi:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Giờ đây, thông qua sức mạnh của bản đồ băm, bạn có thể kéo chỉ mục các mục nhập của mình trong thời gian không đổi (hay còn gọi là nhanh hơn rất nhiều)


1

oh, đó là một khó khăn. Những gì bạn có ở đây, về cơ bản, là hai giá trị cho mỗi mục. Sau đó, bạn đang cố gắng gọi cho họ bằng một số làm chìa khóa. Rất tiếc, một trong các giá trị của bạn đã được đặt làm khóa!

Thử đi:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Bây giờ bạn có thể gọi các khóa theo số như thể chúng được lập chỉ mục giống như một danh sách. Bạn cũng có thể tham khảo màu và số theo vị trí của chúng trong danh sách.

Ví dụ,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

Tất nhiên, bạn sẽ phải nghĩ ra một cách khác để theo dõi vị trí của từng màu. Có thể bạn có thể có một từ điển khác lưu trữ khóa của từng màu như giá trị của nó.

color_key = {'blue': 1, 'red': 6, 'yllow': 8}

Sau đó, bạn cũng có thể tra cứu phím màu nếu cần.

color [Colors_key ['blue']] [0] sẽ trả về 'blue'

Đại loại vậy.

Và sau đó, trong khi bạn đang ở đó, bạn có thể tạo ra một mệnh đề với các giá trị số làm khóa để bạn luôn có thể sử dụng chúng để tra cứu màu sắc của mình, bạn biết đấy, nếu bạn cần.

giá trị = {5: [1, 'blue'], 6: [2, 'red'], 8: [3, 'yellow']}

Sau đó, (màu sắc [khóa_màu sắc [giá_trị [5] [1]]] [0]) sẽ trả về 'xanh lam'.

Hoặc bạn có thể sử dụng một danh sách các danh sách.

Chúc may mắn!


0

Bạn không thể, vì dictkhông có thứ tự. bạn có thể sử dụng .popitem()để lấy một mục tùy ý, nhưng điều đó sẽ xóa nó khỏi dict.


next(iter(d.items()))( .iteritems()trong Python 2) cũng cung cấp cho bạn một mục tùy ý (điều tương tự trong các thử nghiệm của tôi, điều này có ý nghĩa vì popitem có thể được triển khai bằng cách sử dụng này) nhưng sẽ không xóa mục đó.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.