应用于列表的Append()进入循环

时间:2017-03-10 19:22:37

标签: python list loops

我是Python新手,正如您所看到的,我正在尝试研究对象编程。 在下一个代码中,我试图模拟运输物品的卡车:每件物品都有标识符和重量。轨道具有最大重量容量。看看下面的代码,我会告诉你这个问题。

class Item():
    '''
    Class Item models an object transported in a supply chain
    '''
    def __init__(self, id, weight):
        '''
        Constructor of an object of class Item
        :param id: Unique identifier of the Item
        :param weight: the weight of the Item, expressed in Kg
        '''

        self.id = id
        self.weight = weight

class Truck():
    '''
    Class Truck models a truck transporting Items
    '''

    def __init__(self, plate_number, capacity):
        '''
        Constructor of an object of class Truck
        :param plate_number: Unique identifier of the Truck
        :param capacity: maximum weight transportable by the Truck
        '''
        self.plate_number = plate_number
        self.capacity = capacity
        self.remaining_capacity = capacity

    def load(self, items):
        '''
        This method allows to load a list of items into a truck if their
        total weight is less that or equal to the remaining capacity of the truck.
        If this is case, True is returned. Otherwise False is returned
        :param items:
        :return:
        '''

        total_load = 0
        for item in items:
            total_load += item.weight

            if total_load > self.remaining_capacity:
            print('out of range')
            return False
        else:
            for item in items:
                items.append(item)
                self.remaining_capacity = self.remaining_capacity - item.weight
            return True

    a = Item('AAA01', 10)
    b = Item('BBB01', 20)
    c = Item('CCC01', 30)

    truck_a = Truck('LE000A', 35)
    truck_a.load([a, b])

    print('Remaining capcity of Truck ', truck_a.plate_number, ' is ',truck_a.remaining_capacity)

在Trucks的load(items)方法中,您可以看到命令items.append(item):如果该命令有效,则整体程序可以正常工作;如果没有,它会循环,但我无法想象为什么。

修改 使用下一个代码似乎可行,而不更改 items.append(item) 语句

class Item():
'''
Class Item models an object transported in a supply chain
'''
def __init__(self, id, weight):
    '''
    Constructor of an object of class Item
    :param id: a unique code associated to the item
    :param weight: the weight of the item expressed in kg
    '''
    self.id = id
    self.weight = weight
class Truck():
'''
This class models a truck
'''
def __init__(self, plate_number, capacity, items):
    '''
    Clonstructor of an object of class Truck
    :param plate_number: a unique number Identifying the truck
    :param capacity: maximum weight that the truck can carry
    :param items: list of objects of class Item carried by the truck
    '''
    self.plate_number = plate_number
    self.capacity = capacity
    self.items = list(items)
    self.remaining_capacity = capacity
    for item in self.items:
            self.remaining_capacity = self.remaining_capacity - item.weight

def load(self, items):
    '''
    This method allows to load a list of items into a truck if their
    total weight is less that or equal to the remaining capacity of the truck.
    If this is case, True is returned. Otherwise False is returned
    :param items:
    :return:
    '''
    total_load = 0
    for item in items:
        total_load = item.weight
    if total_load > self.remaining_capacity:
        return False
    else:
        for item in items:
            self.items.append(item)
            self.remaining_capacity = self.remaining_capacity - item.weight
            return True

a = Item('AAA01', 10)
b = Item('BBB01', 20)
c = Item('CCC01', 30)

truck_a = Truck('LE000A', 35, [a])
truck_a.load([b])

print('Remaining capacity of Truck ', truck_a.plate_number, ' is ', truck_a.remaining_capacity)

正如您所看到的,EDIT代码的主要区别在于class Truck有一个构造函数,它将items作为参数并使用self.items = list(items)对其进行“复制”。我不知道为什么最后一个代码一直在工作

3 个答案:

答案 0 :(得分:2)

在我看来,您正试图记录卡车上的内容......您需要添加self.items属性,然后将项目附加到该项:

def __init__(self, plate_number, capacity):
    ...
    self.items = []  # Items on the truck

然后在load()中,您可以通过self.items.append()添加项目:

else:
    for item in items:
        self.items.append(item)
        self.remaining_capacity = self.remaining_capacity - item.weight
    return True

如果您在第一次和第二次尝试时比较以下功能的运行,您将看到原因:

def attributes(obj):
    return [s for s in dir(obj) if s[0] != '_']

print attributes(truck_a)

在第一种情况下,它不会有任何items列表,因为您没有为其分配一个(self.items)。完成后,它会有一个属性items,可以通过self.items在课程中访问。这与传入的参数items不同。您可以通过使用不同的名称来减少混淆:

def load(self, items_to_load):
    ...
    for item_to_load in items_to_load:
        self.items.append(item_to_load)

答案 1 :(得分:1)

正如前面的评论和回答中所提到的,您将迭代列表中每次迭代添加项目的项目,从而生成无限循环。如上所述,items += items将适用于此案例。但是,您面临的一般问题是如何在迭代它们时更改列表中的项目。最好的方法是迭代列表的副本,如下所示:

>>> items = [1, 2, 3]
>>> for item in items[:]:
        items.append(item)


>>> items
[1, 2, 3, 1, 2, 3]
>>> 

items[:]items的一部分,由items的所有成员组成,根据定义,它是items的副本。对于无法切片的词典,请使用copy()方法。

答案 2 :(得分:0)

你的 for 循环会改变相反,尝试这个:列表,当它在列表中迭代时。你永远无法达到目的,因为你在工作的同时不断扩展它。您要对列表进行什么操作?如果你想要的只是一个元素加倍的列表,你可以使用

items += items

这是一个简短的说明:

items = ["hello", 17, True]

for item in items:
    items.append(item)
    print items

输出:

['hello', 17, True, 'hello']
['hello', 17, True, 'hello', 17]
['hello', 17, True, 'hello', 17, True]
['hello', 17, True, 'hello', 17, True, 'hello']
['hello', 17, True, 'hello', 17, True, 'hello', 17]
['hello', 17, True, 'hello', 17, True, 'hello', 17, True]
...