You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python计算任意数量线段长度?代码报错及概念疑问

Let's fix your code step by step and break down the issues you're facing.

First, let's address the "tuple cannot be used as operand for subtraction" error

The main culprit here is how you're handling coordinates in the distance function and how you're initializing Point objects in LineString.__init__:

  1. Wrong Point initialization:
    In your LineString.__init__, you wrote:

    self.args=[Point(*args) for p in args]
    

    Here, args is the collection of coordinate tuples (like (1,1) or (0,2)). For each p in args, you need to unpack p (not the entire args tuple) to create a Point. So it should be Point(*p).

  2. Broken distance calculation:

    • Your formula has a critical typo: the distance between two points uses the sum of squared differences, not the difference of squares.
    • You’re packing p1.x, p1.y into a tuple a, then trying to do a**2 — tuples don’t support arithmetic operations like exponentiation or subtraction directly. You don’t need these tuples at all; just use the x and y attributes directly for calculations.

Next, fix missing methods and syntax issues

Your code is missing two essential methods for LineString, plus a syntax error in imports:

  • move: To shift all points in the LineString (you’re calling this method but haven’t implemented it)
  • __getitem__: To allow indexing like lin1[0] or lin2[-1]
  • The import line is invalid: split from itertools import starmap and import math into separate lines.

Corrected Full Code

from itertools import starmap
import math

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def move(self, dx, dy):
        self.x += dx
        self.y += dy

class LineString(object):
    def __init__(self, *args):
        # Correctly create Point instances from each coordinate tuple
        self.points = [Point(*p) for p in args]
    
    def move(self, dx, dy):
        # Move every point in the LineString
        for point in self.points:
            point.move(dx, dy)
    
    def __getitem__(self, key):
        # Allow indexing to access specific points (e.g., lin1[0], lin2[-1])
        return self.points[key]
    
    def length(self):
        # Pair each point with the next consecutive point
        point_pairs = zip(self.points, self.points[1:])
        return sum(starmap(distance, point_pairs))

def distance(p1, p2):
    # Correct distance formula using direct attribute access
    dx = p1.x - p2.x
    dy = p1.y - p2.y
    return math.sqrt(dx**2 + dy**2)

if __name__ == '__main__':
    # Tests for LineString
    # ===================================
    lin1 = LineString((1, 1), (0, 2))
    assert lin1.length() == math.sqrt(2.0)
    lin1.move(-1, -1)
    assert lin1[0].y == 0
    
    lin2 = LineString((1, 1), (1, 2), (2, 2))
    assert lin2.length() == 2.0
    lin2.move(-1, -1)
    assert lin2.length() == 2.0
    assert lin2[-1].x == 1
    
    print('Success! Line tests passed!')

Key Python Concepts You Might Have Missed

Let’s break down the core ideas that were tripping you up:

  • Variable-length arguments (*args): When you define a method with *args, it captures all positional arguments as a tuple. In LineString.__init__, args holds your coordinate tuples — you need to iterate over each tuple and unpack it to create Point instances.
  • Special "dunder" methods: __getitem__ is a special method that lets your class support indexing (like my_obj[0]), making it behave like built-in types such as lists or tuples.
  • Tuple limitations: Tuples are immutable sequences and don’t support arithmetic operations. If you need to do math on coordinate values, access individual numeric attributes instead of packing them into tuples.
  • Method scope: When you call lin1.move(), you need to implement this method in LineString to iterate over all its points and call each Point’s move method — methods on parent objects don’t automatically propagate to child attributes.

内容的提问来源于stack exchange,提问作者Kaleab Woldemariam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:42:49