【问题标题】:compare two element in a function using iterator in python在python中使用迭代器比较函数中的两个元素
【发布时间】:2012-03-07 06:49:26
【问题描述】:

我是 python 新手,在理解和使用类中的迭代器时遇到一个小问题。

def findLargest(shapes):
"""
Returns a tuple containing the elements of ShapeSet with the
   largest area.
shapes: ShapeSet
"""
bestName = shapes.List[:]
for i in shapes.List:
    if i.cmp(i+1)== -1:
        bestName.remove(memo)
    if i.cmp(i+1)==1:
        bestName.remove(i)
for element in bestName:
    stringout=''
    stringout= stringout + 'Element ' + str(element.name) + ' with an area of ' + str(element.area()) + ', '
return stringout

所以基本上,我想比较元素列表的面积并获得面积最大的元素元组。我的问题是将我的元素“i”与元素“i+1”进行比较。我不知道怎么称呼它。为了迭代,我定义了一个方法 iter 和 next() 来迭代shapes.List

有人可以帮助我,或者告诉我实现此功能的好方法。

谢谢

完整代码如下


    from string import *

    class Shape(object):
def area(self):
    raise AttributeException("Subclasses should override this method.")

def cmp(self, other):
    if type(other) != Shape and type(other) !=Square and type(other) !=Triangle and type(other) !=Circle:
        return 'Not a shape!'
    if self.area > other.area:
        return 1
    if self.area == other.area:
        return 0
    if self.area < other.area:
        return -1

    class Square(Shape):
def __init__(self, h, name):
    """
    h: length of side of the square
    """
    self.side = float(h)
    self.name = name
def area(self):
    """
    Returns area of the square
    """
    return self.side**2

def __str__(self):
    return 'Square with side ' + str(self.side)

def __eq__(self, other):
    """
    Two squares are equal if they have the same dimension.
    other: object to check for equality
    """
    return type(other) == Square and self.side == other.side

    class Circle(Shape):
def __init__(self, radius, name):
    """
    radius: radius of the circle
    """
    self.radius = float(radius)
    self.name = name

def area(self):
    """
    Returns approximate area of the circle
    """
    return 3.14159*(self.radius**2)
def __str__(self):
    return 'Circle with radius ' + str(self.radius)
def __eq__(self, other):
    """
    Two circles are equal if they have the same radius.
    other: object to check for equality
    """
    return type(other) == Circle and self.radius == other.radius

   # Problem 1: Create the Triangle class

    class Triangle(Shape):
def __init__(self, base, height, name):
    self.base= float(base)
    self.height=float(height)
    self.name = name

def area (self):
    area=float(self.base*self.height)/2
    return area

def __str__(self):
    return 'Triangle with a base ' + str(self.base) +' and height ' + str(self.height)

def __eq__ (self, other):
    return type(other)==Triangle and self.base == other.base and self.height == other.height

    #Problem 2: Create the ShapeSet class

    class ShapeSet:
def __init__(self):
    """
    Initialize any needed variables
    """
    self.List = []
    self.index=0

def addShape(self, sh):
    """
    Add shape sh to the set; no two shapes in the set may be
    identical
    sh: shape to be added
    """
    if self==[]:
        self.List.append(sh)
    else:
        for shape in self.List:
            if shape == sh:
                return 'This shape already exist'
            if shape.area == sh.area and type(shape) == type(sh):
                return 'This shape already exist'
        self.List.append(sh)

def __iter__(self):
    """
    Return an iterator that allows you to iterate over the set of
    shapes, one shape at a time
    """
    return self

def next():
    if self.index>len(self.List-1):
        StopIteration
    else:
        self.index+=1
        return self.List[self.index-1]


def __str__(self):
    """
    Return the string representation for a set, which consists of
    the string representation of each shape, categorized by type
    (circles, then squares, then triangles)
    """
    triangleList=[]
    squareList=[]
    circleList=[]
    if self.List == []:
        return 'The set is empty'
    else:
        for element in self.List:
            if type(element)==Triangle:
                triangleList.append(element.name)
            elif type(element)==Square:
                squareList.append(element.name)
            elif type(element)==Circle:
                circleList.append(element.name)
        return 'circles: %s, square: %s, triangle: %s' % (circleList, squareList, triangleList)

【问题讨论】:

  • ShapeSet 应该是 list(或 UserList)的子类,这样会更简单。
  • 此外,由于 Square、Triangle 等子类为Shape,您可以将if type(other)... 的行替换为assert isinstance(other, Shape)。在 __cmp__ 中,您正在比较 area(这是一个函数)而不是 area()(这是此函数的结果。

标签: python list class function iterator


【解决方案1】:

在你的类中,实现__cmp__而不是cmp,那么你就可以使用Python builtins,比如:

bestName = max(shapes.List)

【讨论】:

  • 这应该是评论,而不是答案
  • 我想这不是他问题的答案,但它似乎是解决他问题的更好方法 =)
  • 这绝对是解决这个问题的最好方法,假设他不打算将 cmp 用于其他事情
【解决方案2】:

您可以使用itertools module documentation 中的pairwise recipe

from itertools import tee, izip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

for previous, current in pairwise(shapes.List):
    # etc

或者你可以先找到最大面积:

max_area = max(shapes, lambda s: s.area())

然后使用它来查找该区域的所有元素:

result = [s for s in shapes if s.area() == max_area]

【讨论】:

    【解决方案3】:
    class shape():
        def __init__(self,side_length):
            self.side_length=side_length
        def area(self):
            return self.side_length*self.side_length
    
    shape_list=[shape(i) for i in [1,6,3,12,9]]
    import heapq
    largest_3=heapq.nlargest(3,shape_list,key=shape.area)
    
    for shape in largest_3:
        print shape.side_length
    
    12
    9
    6
    

    【讨论】:

      猜你喜欢
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 2017-08-29
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多