Trừ 2 danh sách bằng Python


84

Ngay bây giờ tôi có các giá trị vector3 được biểu thị dưới dạng danh sách. có cách nào để trừ 2 trong số này như các giá trị vector3, như

[2,2,2] - [1,1,1] = [1,1,1]

Tôi có nên sử dụng bộ giá trị không?

Nếu không ai trong số họ định nghĩa các toán hạng này trên các kiểu này, tôi có thể định nghĩa nó thay thế không?

Nếu không, tôi có nên tạo một lớp vector3 mới không?

Câu trả lời:


134

Nếu đây là việc bạn thường xuyên làm và với các thao tác khác nhau, có lẽ bạn nên tạo một lớp để xử lý các trường hợp như thế này hoặc tốt hơn là sử dụng một số thư viện như Numpy .

Nếu không, hãy tìm hiểu danh sách được sử dụng với chức năng nội trang zip :

[a_i - b_i for a_i, b_i in zip(a, b)]

83

Đây là một thay thế cho danh sách hiểu. Bản đồ lặp lại qua (các) danh sách (các đối số sau), làm như vậy một cách mô phỏng và chuyển các phần tử của chúng làm đối số cho hàm (đối số đầu tiên). Nó trả về danh sách kết quả.

map(operator.sub, a, b)

Mã này vì có ít cú pháp hơn (đối với tôi thẩm mỹ hơn) và rõ ràng là nó nhanh hơn 40% đối với danh sách có độ dài 5 (xem nhận xét của bobince). Tuy nhiên, một trong hai giải pháp sẽ hoạt động.


Tôi thường thấy khả năng hiểu danh sách được đề xuất qua map (), mặc dù điều đó có thể chỉ là do mã trông sạch hơn ... không chắc chắn về sự khác biệt hiệu suất, nếu có.
David Z

2
Bản đồ () xuất hiện nhanh hơn gần 40% đối với tôi trên Py2.6 đối với phép trừ năm phần tử. Tính toàn diện mới hơn và rõ ràng hơn khi chúng tránh được lambda, nhưng để lập bản đồ các chức năng hiện có, bản đồ vẫn có thể khá ... đặc biệt là ở đây, nơi bạn có thể tận dụng zip tích hợp.
bobince 11/02/09

1
này cũng làm việc cho array.array (mặc dù kết quả là một danh sách)
Gens

5
cần có mệnh đề 'nhà điều hành nhập khẩu'; int .__ sub__ làm thủ thuật tốt hơn))
garej

13

Nếu danh sách của bạn là a và b, bạn có thể làm:

map(int.__sub__, a, b)

Nhưng có lẽ bạn không nên. Sẽ không ai biết nó có nghĩa là gì.


1
Tự mình chạy vào đây với phao. Trong trường hợp nào map(float.__sub__, a, b)hoạt động. Cảm ơn vì tiền hỗ trợ!
S3DEV

9

Tôi phải khuyên NumPy cũng

Nó không chỉ nhanh hơn để làm toán vector mà còn có rất nhiều chức năng tiện lợi.

Nếu bạn muốn thứ gì đó nhanh hơn cho vectơ 1d, hãy thử vop

Nó tương tự như MatLab, nhưng miễn phí và nhiều thứ. Đây là một ví dụ về những gì bạn sẽ làm

from numpy import matrix
a = matrix((2,2,2))
b = matrix((1,1,1))
ret = a - b
print ret
>> [[1 1 1]]

Bùng nổ.


1
np.arraysẽ là một giải pháp đơn giản
garej

6

Nếu bạn có hai danh sách được gọi là 'a' và 'b', bạn có thể thực hiện: [m - n for m,n in zip(a,b)]



4

Một lớp Vector hơi khác.

class Vector( object ):
    def __init__(self, *data):
        self.data = data
    def __repr__(self):
        return repr(self.data) 
    def __add__(self, other):
        return tuple( (a+b for a,b in zip(self.data, other.data) ) )  
    def __sub__(self, other):
        return tuple( (a-b for a,b in zip(self.data, other.data) ) )

Vector(1, 2, 3) - Vector(1, 1, 1)

3

Nếu bạn có kế hoạch thực hiện nhiều hơn một lớp lót đơn giản, thì tốt hơn là nên triển khai lớp của riêng bạn và ghi đè các toán tử thích hợp khi chúng áp dụng cho trường hợp của bạn.

Lấy từ Toán học bằng Python :

class Vector:

  def __init__(self, data):
    self.data = data

  def __repr__(self):
    return repr(self.data)  

  def __add__(self, other):
    data = []
    for j in range(len(self.data)):
      data.append(self.data[j] + other.data[j])
    return Vector(data)  

x = Vector([1, 2, 3])    
print x + x

2

Đối với một người từng viết mã trên Pycharm, nó cũng hồi sinh những người khác.

 import operator
 Arr1=[1,2,3,45]
 Arr2=[3,4,56,78]
 print(list(map(operator.sub,Arr1,Arr2)))

1

Sự kết hợp của mapvà các lambdahàm trong Python là một giải pháp tốt cho loại vấn đề này:

a = [2,2,2]
b = [1,1,1]
map(lambda x,y: x-y, a,b)

zip chức năng là một lựa chọn tốt khác, như được chứng minh bởi @UncleZeiv


0
arr1=[1,2,3]
arr2=[2,1,3]
ls=[arr2-arr1 for arr1,arr2 in zip(arr1,arr2)]
print(ls)
>>[1,-1,0]

2
Mặc dù đoạn mã này có thể là giải pháp, nhưng bao gồm phần giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Narendra Jadhav

0

Câu trả lời này cho thấy cách viết mã pythonic "bình thường / dễ hiểu".

Tôi đề nghị không sử dụng zipvì không thực sự mọi người đều biết về nó.


Các giải pháp sử dụng khả năng hiểu danh sách và các chức năng tích hợp phổ biến.


Phương án 1 (Khuyến nghị):

a = [2, 2, 2]
b = [1, 1, 1]
result = [a[i] - b[i] for i in range(len(a))]

Được khuyến nghị vì nó chỉ sử dụng các chức năng cơ bản nhất trong Python


Phương án 2:

a = [2, 2, 2]
b = [1, 1, 1]
result = [x - b[i] for i, x in enumerate(a)]

Phương án 3 (như được đề cập bởi BioCoder ):

a = [2, 2, 2]
b = [1, 1, 1]
result = list(map(lambda x, y: x - y, a, b))

Tại sao lại ủng hộ? Câu trả lời của tôi là duy nhất và có thể giúp ích cho người khác.
Timmy Chan

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.