Nếu tôi có một từ điển Python, làm thế nào để tôi lấy khóa cho mục nhập chứa giá trị tối thiểu?
Tôi đã suy nghĩ về một cái gì đó để làm với min()
chức năng ...
Đưa ra đầu vào:
{320:1, 321:0, 322:3}
Nó sẽ trở lại 321
.
Nếu tôi có một từ điển Python, làm thế nào để tôi lấy khóa cho mục nhập chứa giá trị tối thiểu?
Tôi đã suy nghĩ về một cái gì đó để làm với min()
chức năng ...
Đưa ra đầu vào:
{320:1, 321:0, 322:3}
Nó sẽ trở lại 321
.
Câu trả lời:
Tốt nhất: min(d, key=d.get)
- không có lý do gì để can thiệp vào một lambda
lớp không xác định vô dụng hoặc trích xuất các mục hoặc khóa!
[11, 22, 33]
, ví dụ , thay vì từ điển, vd {1: 11, 2:22, 3:33}
. 'D.get' là hợp lệ cho một từ điển, nhưng không phải cho một danh sách.
d={"a":[10, None], "b":[20, None]}
, trong đó min được tính từ d [key] [0]?
min()
trả về giá trị trong giá trị đầu tiên được sắp xếp khóa chỉ định cách sắp xếp các giá trị. key=d.get
có nghĩa là danh sách sẽ được sắp xếp theo các giá trị của từ điển.
Đây là một câu trả lời thực sự mang lại giải pháp mà OP yêu cầu:
>>> d = {320:1, 321:0, 322:3}
>>> d.items()
[(320, 1), (321, 0), (322, 3)]
>>> # find the minimum by comparing the second element of each tuple
>>> min(d.items(), key=lambda x: x[1])
(321, 0)
d.iteritems()
Tuy nhiên, việc sử dụng sẽ hiệu quả hơn đối với các từ điển lớn hơn.
operator.itemgetter(1)
.
Đối với nhiều khóa có giá trị thấp nhất bằng nhau, bạn có thể sử dụng cách hiểu danh sách:
d = {320:1, 321:0, 322:3, 323:0}
minval = min(d.values())
res = [k for k, v in d.items() if v==minval]
[321, 323]
Một phiên bản chức năng tương đương:
res = list(filter(lambda x: d[x]==minval, d))
>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k])
321
key=d.get
là tốt hơn.
Đối với trường hợp bạn có nhiều khóa tối thiểu và muốn giữ cho nó đơn giản
def minimums(some_dict):
positions = [] # output variable
min_value = float("inf")
for k, v in some_dict.items():
if v == min_value:
positions.append(k)
if v < min_value:
min_value = v
positions = [] # output variable
positions.append(k)
return positions
minimums({'a':1, 'b':2, 'c':-1, 'd':0, 'e':-1})
['e', 'c']
Nếu bạn không chắc chắn rằng bạn không có nhiều giá trị tối thiểu, tôi sẽ đề xuất:
d = {320:1, 321:0, 322:3, 323:0}
print ', '.join(str(key) for min_value in (min(d.values()),) for key in d if d[key]==min_value)
"""Output:
321, 323
"""
Chỉnh sửa: đây là câu trả lời cho câu hỏi ban đầu của OP về khóa tối thiểu, không phải câu trả lời tối thiểu.
Bạn có thể lấy các khóa của dict bằng keys
hàm và bạn có quyền sử dụng min
để tìm mức tối thiểu của danh sách đó.
Một cách tiếp cận khác để giải quyết vấn đề của nhiều khóa có cùng giá trị tối thiểu:
>>> dd = {320:1, 321:0, 322:3, 323:0}
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>>
>>> print [v for k,v in groupby(sorted((v,k) for k,v in dd.iteritems()), key=itemgetter(0)).next()[1]]
[321, 323]
Sử dụng min
với một iterator (để sử dụng python 3 items
thay vì iteritems
); thay vì lambda sử dụng itemgetter
toán tử từ, nhanh hơn lambda.
from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))
d={}
d[320]=1
d[321]=0
d[322]=3
value = min(d.values())
for k in d.keys():
if d[k] == value:
print k,d[k]
Tôi đã so sánh cách ba tùy chọn sau thực hiện:
import random, datetime
myDict = {}
for i in range( 10000000 ):
myDict[ i ] = random.randint( 0, 10000000 )
# OPTION 1
start = datetime.datetime.now()
sorted = []
for i in myDict:
sorted.append( ( i, myDict[ i ] ) )
sorted.sort( key = lambda x: x[1] )
print( sorted[0][0] )
end = datetime.datetime.now()
print( end - start )
# OPTION 2
start = datetime.datetime.now()
myDict_values = list( myDict.values() )
myDict_keys = list( myDict.keys() )
min_value = min( myDict_values )
print( myDict_keys[ myDict_values.index( min_value ) ] )
end = datetime.datetime.now()
print( end - start )
# OPTION 3
start = datetime.datetime.now()
print( min( myDict, key=myDict.get ) )
end = datetime.datetime.now()
print( end - start )
Đầu ra mẫu:
#option 1
236230
0:00:14.136808
#option 2
236230
0:00:00.458026
#option 3
236230
0:00:00.824048
để tạo một lớp có thứ tự, bạn phải ghi đè 6 hàm đặc biệt, để nó được gọi bởi hàm min ()
các phương thức này __lt__ , __le__, __gt__, __ge__, __eq__ , __ne__
theo thứ tự chúng nhỏ hơn, nhỏ hơn hoặc bằng, lớn hơn, lớn hơn hoặc bằng, bằng nhau, không bằng nhau. ví dụ bạn nên thực hiện __lt__
như sau:
def __lt__(self, other):
return self.comparable_value < other.comparable_value
sau đó bạn có thể sử dụng hàm min như sau:
minValue = min(yourList, key=(lambda k: yourList[k]))
Điều này làm việc cho tôi.
min(zip(d.values(), d.keys()))[1]
Sử dụng hàm zip để tạo một bộ lặp gồm các bộ chứa các giá trị và khóa. Sau đó bọc nó bằng một hàm tối thiểu lấy tối thiểu dựa trên khóa đầu tiên. Điều này trả về một cặp chứa (giá trị, khóa). Chỉ số của [1] được sử dụng để lấy khóa tương ứng
# python
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
321
min()
).
Đây có phải là những gì bạn đang tìm kiếm?
d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'
print d[min(d.keys())]
In 'mười bốn'