2010-09-08 49 views
10

Tôi có một hàm được chuyển hai giá trị và sau đó lặp lại trong phạm vi của các giá trị đó. Các giá trị có thể được truyền theo bất kỳ thứ tự nào, vì vậy tôi cần phải tìm giá trị nào thấp nhất trước. Tôi đã có chức năng viết như thế này:Cách tốt nhất để tìm tối đa và tối thiểu của hai giá trị

def myFunc(x, y): 
    if x > y: 
     min_val, max_val = y, x 
    else: 
     min_val, max_val = x, y 
    for i in range(min_val, max_val): 
    ... 

Tuy nhiên, để tiết kiệm một số không gian màn hình, tôi đã kết thúc thay đổi nó để:

def myFunc(x, y): 
    min_val, max_val = sorted([x, y]) 
    for i in range(min_val, max_val): 
    ... 

Làm thế nào xấu là điều này? Có cách nào tốt hơn vẫn là một dòng không?

Trả lời

4

Trừ khi bạn cần phải microoptimise, tôi muốn chỉ để này

def myFunc(x, y): 
    for i in range(*sorted((x, y))): 
     ... 

này nhanh hơn mặc dù

def myFunc(x, y): 
    for i in range(x,y) if x<y else range(y,x): 
     ... 

minmax.py

def f1(x, y): 
    for i in range(min(x, y), max(x, y)): 
     pass 

def f2(x, y): 
    for i in range(*sorted((x, y))): 
     pass 

def f3(x, y): 
    for i in range(x, y) if x<y else range(y, x): 
     pass 

def f4(x, y): 
    if x>y: 
     x,y = y,x 
    for i in range(x, y): 
     pass 

def f5(x, y): 
    mn,mx = ((x, y), (y, x))[x>y] 
    for i in range(x,y): 
     pass 

chuẩn (f3 là nhanh nhất r egardless của trật tự)

$ python -m timeit -s"import minmax as mm" "mm.f1(1,2)" 
1000000 loops, best of 3: 1.93 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f2(1,2)" 
100000 loops, best of 3: 2.4 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f3(1,2)" 
1000000 loops, best of 3: 1.16 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f4(1,2)" 
100000 loops, best of 3: 1.2 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f5(1,2)" 
1000000 loops, best of 3: 1.58 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f1(2,1)" 
100000 loops, best of 3: 1.88 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f2(2,1)" 
100000 loops, best of 3: 2.39 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f3(2,1)" 
1000000 loops, best of 3: 1.18 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f4(2,1)" 
1000000 loops, best of 3: 1.25 usec per loop 
$ python -m timeit -s"import minmax as mm" "mm.f5(2,1)" 
1000000 loops, best of 3: 1.44 usec per loop 
15

minmax là bạn của bạn.

def myFunc(x, y): 
    min_val, max_val = min(x, y), max(x, y) 

Chỉnh sửa. Đã đánh dấu min-max phiên bản againt đơn giản if. Do chi phí cuộc gọi chức năng, min-max mất 2.5x dài hơn là đơn giản if; xem http://gist.github.com/571049

+0

tôi đã thậm chí không nghĩ đến việc làm điều đó trong một dòng. Nhưng tùy thuộc vào cách sắp xếp được thực hiện, nó thực sự có thể kém hiệu quả hơn. Tôi biết sắp xếp thư viện chuẩn trong C++ được mã hóa cứng cho <7 phần tử, do đó việc sắp xếp danh sách hai phần tử sẽ chỉ là một so sánh đơn. Tuy nhiên, có thêm chi phí tạo ra một đối tượng danh sách. – Colin

4

Tôi thích số sorted. Thông minh nhưng không quá thông minh. Dưới đây là một số tùy chọn khác.

def myFunc(min, max): 
    if min > max: min, max = max, min 

def myFunc(x, y): 
    min, max = min(x, y), max(x, y) 

def myFunc(x, y): 
    min, max = [f(x, y) for f in (min, max)] 

Điều cuối cùng một chút ngớ ngẩn mà tôi thừa nhận.

+2

Tốt nhất nên sử dụng các tên khác hơn min và max, vì chúng được xây dựng bằng Python. –

1

Một số gợi ý

def myfunc(minVal, maxVal): 
    if minVal > maxVal: minVal, maxVal = maxVal, minVal 

def myfunc2(a, b): 
    minVal, maxVal = ((a, b), (b, a))[a > b] # :-P 

Sử dụng sắp xếp, các min/max builtins hoặc giải pháp thứ hai dường như trên quá mức cần thiết trong trường hợp này.

Và hãy nhớ rằng range(min, max) sẽ lặp lại từ min đến max - 1!

2

Câu trả lời tốt nhất duy nhất hoạt động như:

def foo(lo, hi): 
    if hi < lo: lo,hi = hi,lo 

Rõ ràng, làm cho một điểm, và không ý nghĩa mơ hồ trong một loạt các keo thêm. Nó ngắn. Nó gần như chắc chắn nhanh như bất kỳ lựa chọn nào khác trong thực tế, và nó dựa vào số lượng thông minh ít nhất.

4

Kể từ khi câu hỏi của OP đã được đặt ra sử dụng xy như các tham số (không lohi), tôi sẽ đi với (cho cả tốc độ và rõ ràng):

def myfunc(x, y): 
    lo, hi = (x, y) if x < y else (y, x) 

>>> timeit.repeat("myfunc(10, 5)", "from __main__ import myfunc") 
[1.2527812156004074, 1.185214249195269, 1.1886092749118689] 
>>> timeit.repeat("foo(10, 5)", "from __main__ import foo") 
[1.0397177348022524, 0.9580022495574667, 0.9673979369035806] 
>>> timeit.repeat("f3(10, 5)", "from __main__ import f3") 
[2.47303065772212, 2.4192818561823515, 2.4132735135754046] 
+0

sử dụng tốt giải nén, tôi thích câu trả lời này tốt nhất – timgeb

Các vấn đề liên quan