Truy cập một phần tử tùy ý trong một từ điển trong Python


507

Nếu a mydictkhông trống, tôi truy cập một phần tử tùy ý là:

mydict[mydict.keys()[0]]

Có cách nào tốt hơn để làm điều này?


3
Những gì anh ấy nói .. đây thực sự chỉ là một câu hỏi hợp lệ nếu chỉ có một yếu tố trong chính tả, hoặc bạn không quan tâm bạn sẽ nhận lại được gì.
hoàng gia

5
Vâng, tôi chỉ cần truy cập vào bất kỳ yếu tố nào trong dict, vì vậy đó là lý do tại sao tôi muốn truy cập vào yếu tố đầu tiên.
Stan

2
@Stan: nhưng như Greg đã nói, không có yếu tố "đầu tiên" nhất định trong dict. vì vậy có lẽ bạn nên thay đổi câu hỏi của mình, để rõ ràng
tdihp

10
Tôi nghĩ đó là một câu hỏi hợp lệ. Nếu bạn cần truy cập một yếu tố tùy ý và bạn chắc chắn rằng chính tả không trống, có thể nên hỏi "đầu tiên", vì số lượng vật phẩm có thể không được biết.
kap

7
@MichaelScheper Bạn phải chọn vào danh sách : list(mydict.keys())[0].
Daniel Moskovich

Câu trả lời:


600

Trên Python 3, không phá hủy và lặp lại:

next(iter(mydict.values()))

Trên Python 2, không phá hủy và lặp lại:

mydict.itervalues().next()

Nếu bạn muốn nó hoạt động trong cả Python 2 và 3, bạn có thể sử dụng sixgói:

six.next(six.itervalues(mydict))

mặc dù tại thời điểm này nó khá khó hiểu và tôi thích mã của bạn hơn.

Nếu bạn muốn xóa bất kỳ mục nào, hãy làm:

key, value = mydict.popitem()

Lưu ý rằng "đầu tiên" có thể không phải là một thuật ngữ thích hợp ở đây vì dictkhông phải là loại có thứ tự trong Python <3.6. Python 3.6+ dictsđược đặt hàng.


35
Ý bạn là dict.iterkeys().next()sao?
John Machin

12
@ John Machin: Chà, câu hỏi dường như truy cập giá trị liên quan đến khóa đầu tiên, vì vậy đó cũng là những gì tôi làm trong câu trả lời.
đôi

5
cái này có vẻ tốt hơn: dict.values().__iter__().__next__():)
Vitaly Zdanevich

17
thật khó chịu khi dict.keys () không thể lặp lại trực tiếp.
nửa

3
đối với một quần thể không phá hủy, bạn có thể tạo một bản sao (nông):key, value = dict(d).popitem()
Pelle

140

Nếu bạn chỉ cần truy cập một yếu tố (là người đầu tiên tình cờ, vì các điều khoản không đảm bảo việc đặt hàng), bạn có thể chỉ cần làm điều này trong Python 2 :

my_dict.keys()[0]     -> key of "first" element
my_dict.values()[0]   -> value of "first" element
my_dict.items()[0]    -> (key, value) tuple of "first" element

Xin lưu ý rằng (theo hiểu biết của tôi) Python không đảm bảo rằng 2 cuộc gọi liên tiếp đến bất kỳ phương thức nào trong số này sẽ trả về danh sách với cùng một thứ tự. Điều này không được hỗ trợ với Python3.

trong Python 3 :

list(my_dict.keys())[0]     -> key of "first" element
list(my_dict.values())[0]   -> value of "first" element
list(my_dict.items())[0]    -> (key, value) tuple of "first" element

90
Điều đó chỉ hoạt động trong Python 2.x, với 3.x bạn phải sử dụnglist(my_dict.keys())[0]
alldayremix

6
Vì vậy, lớp phức tạp này là gì? Chắc chắn list(my_dict.keys())[0]là không lười biếng?
Evgeni Sergeev

1
Để làm rõ, ý nghĩa của @alldayremix với nhận xét đó là trong kết quả python 3.x my_dict.feft () không hỗ trợ lập chỉ mục, đây là lý do tại sao trước hết chúng ta phải chuyển đổi nó thành một danh sách và sau đó chúng ta có thể sử dụng chỉ mục [0]
Noki

57

Trong python3, Cách:

dict.keys() 

trả về một giá trị theo loại: dict_keys (), chúng tôi sẽ gặp lỗi khi có thành viên thứ nhất của khóa dict theo cách này:

dict.keys()[0]
TypeError: 'dict_keys' object does not support indexing

Cuối cùng, tôi chuyển đổi dict.keys () thành list @ 1st và có thành viên thứ 1 theo phương thức splice danh sách:

list(dict.keys())[0]

Đây là giải pháp đơn giản nhất và hoạt động trong cả python2 và python3.
mattmilten

Cho tiền của tôi. Tôi nói câu trả lời này là trực quan nhất
Thomas Valadez

Vâng, nhưng điều này không trả lời câu hỏi OP, đó là cách lấy tại GIÁ TRỊ, không phải các phím.
Mike Williamson

1
@MikeWilliamson hy vọng hầu hết độc giả sẽ biết làm thế nào để có được giá trị tương ứng, được cung cấp một khóa, từ một lệnh của con trăn.
eric

5
Để có được một mục tùy ý, không phải là một khóa tùy ý, bạn có thể làm tương tự list(dict.values())[0].
jhin

24

để lấy chìa khóa

next(iter(mydict))

để có được một giá trị

next(iter(mydict.values()))

để có được cả hai

next(iter(mydict.items())) # or next(iter(mydict.viewitems())) in python 2

Hai cái đầu tiên là Python 2 và 3. Hai cái cuối cùng lười biếng trong Python 3, nhưng không phải trong Python 2.


16

Như những người khác đã đề cập, không có "mục đầu tiên", vì từ điển không có thứ tự được đảm bảo (chúng được thực hiện dưới dạng bảng băm). Nếu bạn muốn, ví dụ, giá trị tương ứng với khóa nhỏ nhất, thedict[min(thedict)]sẽ làm điều đó. Nếu bạn quan tâm đến thứ tự các phím được chèn, tức là, "đầu tiên", bạn có nghĩa là "được chèn sớm nhất", thì trong Python 3.1, bạn có thể sử dụng các bộ sưu tập.OrderedDict , cũng nằm trong Python 2.7 sắp tới; đối với các phiên bản cũ hơn của Python, hãy tải xuống, cài đặt và sử dụng backport dict được đặt hàng (2.4 trở lên) mà bạn có thể tìm thấy ở đây .

Python 3.7 Bây giờ các lệnh được chèn theo thứ tự.


11

Còn cái này thì sao. Chưa được đề cập ở đây.

py 2 & 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2

5
dict.values()trả về một khung nhìn, vì vậy nên là O (1). list(a)trả về một danh sách mới, vì vậy sẽ là O (n).
boycy

Ngoài ra, có vẻ như nó không hoạt động trong python2 nếu a = {"a": {"1"}}
qasimzee

11

Bỏ qua các vấn đề xung quanh việc đặt hàng chính tả, điều này có thể tốt hơn:

next(dict.itervalues())

Bằng cách này, chúng tôi tránh tra cứu mục và tạo danh sách các khóa mà chúng tôi không sử dụng.

Python3

next(iter(dict.values()))

2
các giá trị () sẽ tạo một bản sao của tất cả các giá trị (cũng như các khóa () cho các khóa), do đó, điều này sẽ thực hiện nhiều thao tác O (n ^ 2).
Glenn Maynard

Vậy phiên bản OP sẽ thế nào? Tôi sẽ thay đổi điều này để sử dụng một trình vòng lặp sau đó.
Matt Joiner

4
Đây chỉ là Python 2. Đối với Python 3, chúng ta cần next(iter(dict.values()))nhận được kết quả tương tự mà không cần tạo danh sách.
kap


2

Bạn luôn có thể làm:

for k in sorted(d.keys()):
    print d[k]

Điều này sẽ cung cấp cho bạn một sự sắp xếp nhất quán (liên quan đến nội dung dung .hash () tôi đoán) mà bạn có thể xử lý nếu việc sắp xếp có ý nghĩa gì với bạn. Điều đó có nghĩa là các loại số ví dụ được sắp xếp một cách nhất quán ngay cả khi bạn mở rộng từ điển.

THÍ DỤ

# lets create a simple dictionary
d = {1:1, 2:2, 3:3, 4:4, 10:10, 100:100}
print d.keys()
print sorted(d.keys())

# add some other stuff
d['peter'] = 'peter'
d['parker'] = 'parker'
print d.keys()
print sorted(d.keys())

# some more stuff, numeric of different type, this will "mess up" the keys set order
d[0.001] = 0.001
d[3.14] = 'pie'
d[2.71] = 'apple pie'
print d.keys()
print sorted(d.keys())

Lưu ý rằng từ điển được sắp xếp khi in. Nhưng bộ khóa về cơ bản là một hashmap!


2

Đối với cả Python 2 và 3:

import six

six.next(six.itervalues(d))

Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ.
Martin Tournoij

Điều này trả lời chính xác câu hỏi Is there any better way to do this?theo cách ngắn gọn.
oblalex

Câu trả lời này đã được đưa ra hai lần rồi, một trong số đó đã có trên trang này trong gần 5 năm. Đây là một nhận xét về một câu trả lời khác (như trong: đây là cách cải thiện câu trả lời để làm cho nó hoạt động với cả Python 2 & 3 ), và không phải là một câu trả lời "mới", như vậy. Hệ thống đánh giá của SO tự động đặt một ghi chú không hữu ích trong trường hợp này ...
Martin Tournoij

Không, thưa ngài. Bạn đã thêm biến thể này vào câu trả lời 5 yo của bạn chỉ 17 giờ trước, 1 giờ sau khi tôi viết câu trả lời này. Hãy thử sử dụng 'find' trên trang này cho từ 'sáu' và bạn sẽ chỉ tìm thấy 6 kết quả trùng khớp trong 2 câu trả lời này. Dù sao, câu trả lời này thực sự làm phiền bạn? Tôi nghĩ rằng điều này có thể giúp đỡ những người khác trong tương lai và điều này là OK. Vậy thỏa thuận là gì?
oblalex

Đó là bởi vì IMHO câu trả lời này đáng lẽ phải là một chỉnh sửa cho bài đăng đó ngay từ đầu. Nếu không chỉnh sửa, mọi người sẽ phải cuộn một số trang xuống để xem câu trả lời của bạn; Bạn có nghĩ rằng điều đó hữu ích hơn việc chỉnh sửa một câu trả lời được đánh giá cao gần giống với câu trả lời của bạn không?
Martin Tournoij

0
first_key, *rest_keys = mydict

11
Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp hạn chế, ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm các giả định bạn đã thực hiện.
Suraj Rao

-1

Không có thư viện bên ngoài, hoạt động trên cả Python 2.7 và 3.x:

>>> list(set({"a":1, "b": 2}.values()))[0]
1

Đối với khóa aribtrary chỉ cần bỏ qua .values ​​()

>>> list(set({"a":1, "b": 2}))[0]
'a'

-2

Phân lớp dictlà một phương thức, mặc dù không hiệu quả. Ở đây nếu bạn cung cấp một số nguyên, nó sẽ trả về d[list(d)[n]], nếu không thì truy cập từ điển như mong đợi:

class mydict(dict):
    def __getitem__(self, value):
        if isinstance(value, int):
            return self.get(list(self)[value])
        else:
            return self.get(value)

d = mydict({'a': 'hello', 'b': 'this', 'c': 'is', 'd': 'a',
            'e': 'test', 'f': 'dictionary', 'g': 'testing'})

d[0]    # 'hello'
d[1]    # 'this'
d['c']  # 'is'
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.