Làm thế nào để bạn tìm thấy khóa đầu tiên trong một từ điển?


199

Tôi đang cố gắng để chương trình của tôi in ra "banana"từ điển. Cách đơn giản nhất để làm điều này là gì?

Đây là từ điển của tôi:

prices = {
    "banana" : 4,
    "apple" : 2,
    "orange" : 1.5,
    "pear" : 3
}

35
Từ điển trong Python không có thứ tự, vì vậy không có "khóa đầu tiên". Xem tại đây
David Robinson

2
Bạn có muốn in nghĩa đen từ "chuối" hoặc giá trị liên quan đến "chuối" (4, trong trường hợp này) không?
Paul H

to print out banana with a FOR loop, so when I run it, each key would also be printed outÝ bạn là for k in prices: print ksao Điều đó sẽ in ra tất cả các khóa trong từ điển.
David Robinson


7
đến bình luận đầu tiên: trong python 3.6+ từ điển được đặt hàng (xem stackoverflow.com/questions/39980323/
mẹo

Câu trả lời:


283

Trên phiên bản Python nơi thực sự đặt hàng, bạn có thể làm

my_dict = {'foo': 'bar', 'spam': 'eggs'}
next(iter(my_dict)) # outputs 'foo'

Để các lệnh được đặt hàng, bạn cần Python 3.7+ hoặc 3.6+ nếu bạn thấy ổn khi dựa vào bản chất được sắp xếp theo thứ tự kỹ thuật của việc thực hiện trên dicts trên Python 3.6.

Đối với các phiên bản Python trước đó, không có "khóa đầu tiên".


29
Nếu bạn muốn cả khóa và giá trị trong Python 3:next(iter( my_dict.items() ))
Jonathan H

@RyanHained Python dicts được sắp xếp bằng cách chèn bắt đầu bằng CPython 3.6 và bất kỳ triển khai Python nào khác bắt đầu với Python 3.7
Boris

1
câu trả lời này làm hỏng phiên gỡ lỗi của tôi mà tôi đã đợi 6 giờ để đến điểm dừng. Đây là rất vexxing.
Michael

127

Một từ điển không được lập chỉ mục, nhưng theo một cách nào đó, đã ra lệnh. Sau đây sẽ cung cấp cho bạn khóa đầu tiên hiện có:

list(my_dict.keys())[0]

24
Điều đó sẽ không dễ dàng hơn nếu chỉ đặt list(my_dict)[0]nó sẽ lấy danh sách các khóa?
Jean-Francois T.

@ Jean-FrancoisT. có
Ryan Hained

Từ điển hiện được đặt hàng trong CPython 3.6 và tất cả các triển khai Python khác bắt đầu với Python 3.7
Boris

51

Cập nhật: kể từ Python 3.7, thứ tự chèn được duy trì, vì vậy bạn không cần OrderedDictở đây. Bạn có thể sử dụng các cách tiếp cận dưới đây với bình thườngdict

Thay đổi trong phiên bản 3.7: Thứ tự từ điển được đảm bảo là thứ tự chèn. Hành vi này là một chi tiết triển khai của CPython từ 3.6.

nguồn


Python 3.6 trở về trước *

Nếu bạn đang nói về một thông thường dict, thì "khóa đầu tiên" không có nghĩa gì cả. Các phím không được sắp xếp theo bất kỳ cách nào bạn có thể phụ thuộc vào. Nếu bạn lặp đi lặp lại, dictbạn có thể sẽ không nhận được "banana"như điều đầu tiên bạn nhìn thấy.

Nếu bạn cần giữ mọi thứ theo thứ tự, thì bạn phải sử dụng OrderedDictvà không chỉ là một từ điển đơn giản.

import collections
prices  = collections.OrderedDict([
        ("banana", 4),
        ("apple", 2),
        ("orange", 1.5),
        ("pear", 3),
])

Nếu sau đó bạn muốn xem tất cả các phím theo thứ tự bạn có thể làm như vậy bằng cách lặp qua nó

for k in prices:
    print(k)

Bạn có thể, thay vào đó, đặt tất cả các khóa vào một danh sách và sau đó làm việc với nó

ks = list(prices)
print(ks[0]) # will print "banana"

Một cách nhanh hơn để có được phần tử đầu tiên mà không tạo danh sách sẽ là gọi nexttrên iterator. Điều này không khái quát độc đáo khi cố gắng để có được nthyếu tố mặc dù

>>> next(iter(prices))
'banana'

* CPython đã đảm bảo thứ tự chèn như một chi tiết triển khai trong 3.6.


Cảm ơn vì lời khuyên. Tôi xin lỗi vì đã không rõ ràng hơn. Tôi chỉ đang cố gắng tìm mã sẽ cho phép tôi in ra "Banana" KHÔNG phải giá trị liên quan đến nó. Cám ơn vì tất cả đóng góp!
slagoy

31

Đối với Python 3 bên dưới sẽ loại bỏ chi phí chuyển đổi danh sách:

first = next(iter(prices.values()))

10

Các dictloại là một thứ tự lập bản đồ, vì vậy không có những điều như một yếu tố "đầu tiên".

Những gì bạn muốn có lẽ là collections.OrderedDict.


hoặc một tên được đặt tên có lẽ nếu nó là bất biến
Joran Beasley

Điều này đã thay đổi kể từ Python 3.6. Từ điển hiện được đặt hàng.
misantroop

1
Về mặt kỹ thuật, bạn muốn yếu tố đầu tiên của các khóa từ điển nếu bạn chắc chắn, chỉ có một khóa.
DBX12

người ta có thể nói mục đầu tiên trong khi lặp qua một lệnh mà ifs đã sửa. Nhưng chúc may mắn tìm ra điều đó.
demongolem

6

Vì vậy, tôi đã tìm thấy trang này trong khi cố gắng tối ưu hóa một điều để lấy khóa duy nhất trong từ điển có độ dài 1 đã biết và chỉ trả lại khóa. Quá trình dưới đây là nhanh nhất cho tất cả các từ điển tôi đã thử lên đến kích thước 700.

Tôi đã thử 7 cách tiếp cận khác nhau và thấy rằng cách này là tốt nhất, trên Macbook 2014 của tôi với Python 3.6:

def first_5():
    for key in biased_dict:
        return key

Kết quả định hình chúng là:

  2226460 / s with first_1
  1905620 / s with first_2
  1994654 / s with first_3
  1777946 / s with first_4
  3681252 / s with first_5
  2829067 / s with first_6
  2600622 / s with first_7

Tất cả các phương pháp tôi đã thử ở đây:

def first_1():
    return next(iter(biased_dict))


def first_2():
    return list(biased_dict)[0]


def first_3():
    return next(iter(biased_dict.keys()))


def first_4():
    return list(biased_dict.keys())[0]


def first_5():
    for key in biased_dict:
        return key


def first_6():
    for key in biased_dict.keys():
        return key


def first_7():
    for key, v in biased_dict.items():
        return key

1
Vì vậy, thực hiện một vòng lặp for và trả về khóa đầu tiên (first_5) có thực sự nhanh nhất như tôi có thể thấy? Cũng là một so sánh tốt đẹp của các phương pháp khác nhau.
PiMathCL Language

1
vâng, và không chỉ nhanh nhất, mà còn nhanh nhất theo một dặm đất nước. Cũng dễ đọc nhất, thuận tiện.
turiyag

4

Cũng đơn giản, câu trả lời theo tôi sẽ là

first = list(prices)[0]

chuyển đổi từ điển thành danh sách sẽ xuất ra các khóa và chúng tôi sẽ chọn khóa đầu tiên từ danh sách.


Đối với python3, không cần tạo một danh sách hoàn toàn mới để chỉ lấy phần tử đầu tiên của nó. Sử dụng tốt hơn next(iter(prices)), như đã được đề xuất bởi các câu trả lời khác.
Normanius

1

Như nhiều người khác đã chỉ ra rằng không có giá trị đầu tiên trong từ điển. Việc sắp xếp trong chúng là tùy ý và bạn không thể tin vào việc sắp xếp giống nhau mỗi khi bạn truy cập từ điển. Tuy nhiên nếu bạn muốn in các phím thì có một vài cách để làm điều đó:

for key, value in prices.items():
    print(key)

Phương pháp này sử dụng gán tuple để truy cập khóa và giá trị. Điều này tiện dụng nếu bạn cần truy cập cả khóa và giá trị vì một số lý do.

for key in prices.keys():
    print(key)

Điều này sẽ chỉ cung cấp quyền truy cập vào các khóa như keys()phương thức ngụ ý.


1

d.keys () [0] để lấy khóa riêng.

Cập nhật: - @AlejoBernardin, không chắc tại sao bạn nói nó không hoạt động. Ở đây tôi đã kiểm tra và nó hoạt động. bộ sưu tập nhập khẩu

prices  = collections.OrderedDict((

    ("banana", 4),
    ("apple", 2),
    ("orange", 1.5),
    ("pear", 3),
))
prices.keys()[0]

'trái chuối'


Đi theo số phiếu, tại sao đây không phải là giải pháp tốt nhất?
GuSuku

18
Điều này hoạt động trong python2 nhưng không phải python3. Trong python3, dict.keys()trả về một 'dict_keys' objectthay vì a list, không hỗ trợ lập chỉ mục.
mavix

LoạiError: đối tượng 'dict_keys' không hỗ trợ lập chỉ mục
anilbey

0

Sử dụng vòng lặp for bao gồm tất cả các khóa trong prices:

for key, value in prices.items():
     print key
     print "price: %s" %value

Đảm bảo rằng bạn thay đổi prices.items()thành prices.iteritems()nếu bạn đang sử dụng Python 2.x


0

Nếu bạn chỉ muốn khóa đầu tiên từ một từ điển, bạn nên sử dụng những gì nhiều người đã đề xuất trước đó

first = next(iter(prices))

Tuy nhiên, nếu bạn muốn đầu tiên và giữ phần còn lại dưới dạng danh sách, bạn có thể sử dụng toán tử giải nén giá trị

first, *rest = prices

Điều tương tự cũng được áp dụng cho các giá trị bằng cách thay thế pricesbằng prices.values()và cho cả khóa và giá trị, bạn thậm chí có thể sử dụng phép gán giải nén

>>> (product, price), *rest = prices.items()
>>> product
'banana'
>>> price
4

Lưu ý: Bạn có thể muốn sử dụng first, *_ = pricesđể chỉ lấy khóa đầu tiên, nhưng tôi thường khuyên bạn nên sử dụng trừ khi từ điển rất ngắn vì nó lặp lại trên tất cả các khóa và tạo danh sách cho restmột số chi phí.

Lưu ý: Như đã đề cập bởi người khác, thứ tự chèn được bảo toàn từ python 3.7 (hoặc về mặt kỹ thuật 3.6) trở lên trong khi các triển khai trước đó nên được coi là thứ tự không xác định.


-3

cách dễ nhất là:

first_key = my_dict.keys()[0]

nhưng đôi khi bạn nên cẩn thận hơn và đảm bảo rằng thực thể của bạn là một danh sách có giá trị vì vậy:

first_key = list(my_dict.keys())[0]

3
Nó tăng lên TypeError: 'dict_keys' object is not subscriptable, ít nhất là với Python 3.8
Eerik Sven Puudist
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.