2009-01-29 56 views
25

Với [1,2,3,4,5], làm thế nào tôi có thể làm một cái gì đó giống nhưPython: Đối với mỗi phần tử danh sách áp dụng một hàm trên danh sách

1/1, 1/2, 1/3,1/4,1/5, ...., 3/1,3/2,3/3,3/4,3/5,.... 5/1,5/2,5/3,5/4,5/5 

Tôi muốn lưu trữ tất cả các kết quả, tìm ra mức tối thiểu, và trả lại hai con số sử dụng để tìm mức tối thiểu. Vì vậy, trong trường hợp tôi đã mô tả ở trên, tôi muốn trả lại (1,5).

Vì vậy, về cơ bản tôi muốn làm một cái gì đó giống như

cho mỗi phần tử i trong danh sách bản đồ một số chức năng trên tất cả các yếu tố trong danh sách, lấy ij như thông số cửa hàng kết quả trong một danh sách tổng thể, tìm giá trị nhỏ nhất trong danh sách chính và trả lại đối số i, j được sử dụng để tính giá trị tối thiểu này.

Trong vấn đề thực sự của tôi, tôi có một đối tượng danh sách/tọa độ và hàm tôi đang sử dụng có hai tọa độ và tính khoảng cách euclide. Tôi đang cố gắng tìm khoảng cách euclide tối thiểu giữa hai điểm bất kỳ nhưng tôi không cần một thuật toán ưa thích.

Trả lời

42

Bạn có thể làm bằng list comprehensionsmin() (mã Python 3.0) này:

>>> nums = [1,2,3,4,5] 
>>> [(x,y) for x in nums for y in nums] 
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)] 
>>> min(_, key=lambda pair: pair[0]/pair[1]) 
(1, 5) 

Lưu ý rằng để chạy trên Python 2.5 bạn sẽ cần phải hoặc là làm cho một trong các đối số một float, hoặc làm from __future__ import division do đó 1/5 bằng một cách chính xác 0,2 thay vì 0.

+1

Lưu ý rằng đối số 'khóa' thành min chỉ được chấp nhận kể từ 2.5 –

+0

Tôi đã sử dụng zip (nums, nums) thay vì listcomp, nhưng nếu không thì đó sẽ là giải pháp của tôi. –

+1

Thực tế, kết quả zip (nums, nums) trong [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)], không chính xác. – Kiv

3

Một số python có thể đọc được:

def JoeCalimar(l): 
    masterList = [] 
    for i in l: 
     for j in l: 
      masterList.append(1.*i/j) 
    pos = masterList.index(min(masterList)) 
    a = pos/len(masterList) 
    b = pos%len(masterList) 
    return (l[a],l[b]) 

Hãy cho tôi biết nếu có điều gì không phải là thông thoáng.

10

Nếu tôi đúng trong suy nghĩ rằng bạn muốn tìm giá trị nhỏ nhất của một hàm cho tất cả các cặp có thể có của 2 yếu tố từ một danh sách ...

l = [1,2,3,4,5] 

def f(i,j): 
    return i+j 

# Prints min value of f(i,j) along with i and j 
print min((f(i,j),i,j) for i in l for j in l) 
+0

Danh sách có tên "l "làm tôi thất vọng một chút. Giải pháp tốt mặc dù :) – Kiv

+0

Vâng, tôi luôn luôn gọi danh sách chung của tôi 'lst'. –

+0

Tôi sẽ thêm một [1:] ở cuối: in min ((1. * i/j, i, j) cho i trong l cho j trong l) [1:] –

2

Làm điều đó một cách mathy ...

nums = [1, 2, 3, 4, 5] 
min_combo = (min(nums), max(nums)) 

Trừ khi, tất nhiên, bạn có âm bản trong đó. Trong trường hợp đó, điều này sẽ không hoạt động vì bạn thực sự muốn các giá trị tuyệt đối tối thiểu và tối đa - tử số phải gần bằng 0 và mẫu số cách xa nó theo một trong hai hướng. Và hai âm bản sẽ phá vỡ nó.

+0

BTW, Không làm những gì câu hỏi yêu cầu. Vâng, đó là giải pháp cho ví dụ đơn giản trong câu hỏi, nhưng nó không nói cách áp dụng một số hàm cho các cặp số. (Hoặc có lẽ câu hỏi đã được cải thiện sau khi câu trả lời này được đăng.) – ToolmakerSteve

3

Nếu bạn không nhớ nhập khẩu các gói NumPy, nó có rất nhiều chức năng tiện lợi được xây dựng trong. Nó có khả năng được nhiều hơn nữa hiệu quả sử dụng các cấu trúc dữ liệu của họ hơn so với danh sách của danh sách, vv

from __future__ import division 

import numpy 

data = numpy.asarray([1,2,3,4,5]) 
dists = data.reshape((1,5))/data.reshape((5,1)) 

print dists 

which = dists.argmin() 
(r,c) = (which // 5, which % 5) # assumes C ordering 

# pick whichever is most appropriate for you... 
minval = dists[r,c] 
minval = dists.min() 
minval = dists.ravel()[which] 
1

Nếu làm việc với Python ≥2.6 (bao gồm 3.x), bạn có thể:

from __future__ import division 
import operator, itertools 

def getmin(alist): 
    return min(
     (operator.div(*pair), pair) 
     for pair in itertools.product(alist, repeat=2) 
    )[1] 

getmin([1, 2, 3, 4, 5]) 

EDIT: Bây giờ tôi nghĩ về nó và nếu tôi nhớ toán học của tôi một cách chính xác, điều này cũng nên đưa ra câu trả lời giả định rằng tất cả các số không tiêu cực:

def getmin(alist): 
    return min(alist), max(alist) 
+1

Nếu OP muốn tính toán khoảng cách euclide, có bộ tạo lặp itertools.combinations sẽ chỉ sinh ra các cặp duy nhất có giá trị khác nhau từ đầu vào. – liori

+0

@ liori: OP dường như không muốn khoảng cách euclide. Cảm ơn bình luận của bạn, anyway, vì nó nhắc tôi về câu hỏi. – tzot

0
>>> nums = [1, 2, 3, 4, 5]  
>>> min(map((lambda t: ((float(t[0])/t[1]), t)), ((x, y) for x in nums for y in nums)))[1] 
(1, 5) 
Các vấn đề liên quan