如何替换列表值

How to replace list values

提问人:juno 提问时间:3/7/2023 最后编辑:Christianjuno 更新时间:3/7/2023 访问量:78

问:

class Classy(object):
    def __init__(self, ):
        self.items = []
        

    def addItem(self, name):
        self.add_item = name
        self.items.append(self.add_item)

        for i in range(len(self.add_item[0])):
            
            if self.items[i] == "bowtie":
                self.items[i] = 4
                return print("Item Added")
            
            if self.items[i] == "tophat":
                self.items[i] = 2
                return print("Item Added") 
                       
            if self.items[i] == "monocle":
                self.items[i] = 5
                return print("Item Added")
            
        return print("NO item added")
            
            
    def getClassiness(self):
        total_classiness = 0
        for item in self.items:
            if item == 4:
                total_classiness += 4

            elif item == 2:
                total_classiness += 2

            elif item == 5:
                total_classiness += 5

        return total_classiness
            
                
me = Classy()

# Should be 0
print(me.getClassiness())

me.addItem("tophat")
# Should be 2
print(me.getClassiness())

me.addItem("bowtie")
me.addItem("jacket")
me.addItem("monocle")
# Should be 11
print(me.getClassiness())

me.addItem("bowtie")
# Should be 11
print(me.getClassiness())

要求是经典项目必须作为输入存储在字符串中,然后将字符串添加到 列表,并且有一种计算经典性的方法。

当前代码的输出为:

0 
Item Added
2
NO item added
NO item added
NO item added
2
NO item added
2

目前,在我的调试中,我可以看到它添加了值“tophat”,然后将其替换为值 2,
但是当涉及到“领结”或“monocle”时,它会将它们添加到列表中,然后不替换值
我想知道为什么它在调用该方法时不会更改值

python-3.x 方法 替换

评论

2赞 jasonharper 3/7/2023
len(self.add_item[0])是传递到的字符串的第一个字符的长度 - 换句话说,它始终为 1,因此在执行替换时,您永远不会检查超过列表的第一个元素。那可能应该相反。.addItem()len(self.items)
1赞 Hoang Minh Quang FX15045 3/7/2023
我不明白“for i in range(len(self.add_item[0])):”部分。add_item不是=“礼帽”吗?所以 add_item[0] = “t”, len = 1。你在这里的观点是什么?

答:

1赞 Zelkins 3/7/2023 #1

问题

执行此操作时,将从 0 枚举到存储在 中的字符串的第一个字符的长度,该字符将始终为 1。所以每次都会从 0 开始,在 1 之前结束(所以只会是 0)。for i in range(len(self.add_item[0])):iself.add_itemii

因此,第一项“tophat”起作用,因为当您将 tophat 添加到列表中时,它看起来像这样:(列表仅包含索引 0 处的“tophat”)。因此,该项目在(即 是礼帽,所以会评估为真。append["tophat"]self.items[i]self.items[0]if self.items[i] == "tophat":

块中的下一行将列表中的“tophat”值替换为 2。因此,对于对所有比较语句的每次后续调用,实际上只是将新的第一个值 (2) 与其他字符串(“bowtie”、“tophat”等)进行比较。ifaddItemifself.items[i]

这是代码本身中发生的事情

第一次通话

me.addItem("tophat")
# self.items becomes ["tophat"]
# self.items[i] (where i is 0) equals "tophat"
# self.items[i] becomes 2
# self.items is now ["tophat"]
> "Item Added"

第二次通话

me.addItem("bowtie")
# self.items becomes [2, "bowtie"]
# self.items[i] (where i is 0) does not equal any of the strings, since self.items[0] is 2
# self.items is still [2, "bowtie"]
> "NO item added"

第三次通话

me.addItem("jacket")
# self.items becomes [2, "bowtie", "jacket"]
# self.items[i] (where i is 0) does not equal any of the strings, since self.items[0] is 2
# self.items is still [2, "bowtie", "jacket"]
> "NO item added"

...以此类推,每次后续调用 。addItem


溶液

我认为您打算做的是检查最近添加的项目是否等于您的经典字符串之一。如果你摆脱了循环,只检查了最后一项(使用),你将能够用它的classyness值替换新项目。forself.items[-1]

def addItem(self, name):
    self.add_item = name
    self.items.append(self.add_item)

        
    if self.items[-1] == "bowtie":
        self.items[-1] = 4
        return print("Item Added")
    
    if self.items[-1] == "tophat":
        self.items[-1] = 2
        return print("Item Added") 
                
    if self.items[-1] == "monocle":
        self.items[-1] = 5
        return print("Item Added")
        
    return print("NO item added")

使用此方法的结果将是

0
Item Added   
2
Item Added   
NO item added
Item Added   
11
Item Added   
15

解决方案继续

为了进一步简化代码,我整理了一个不同的版本,该版本产生相同的结果,同时也减少了以后混淆错误的机会。

class Classy(object):

    def __init__(self):
        self.items = []
        self.classy_items = {
            "tophat": 2,
            "bowtie": 4,
            "monocle": 5
        }
        
    def addItem(self, name):
        if name in self.classy_items.keys():
            self.items.append(self.classy_items[name])
            print("Item added")
        else:
            print("NO item added")
            
    def getClassiness(self):
        return sum(self.items)

classy_items将所有经典项及其经典性值存储在键值对字典中。

addItem检查新项是否存在于 in 中,如果存在,则将其值添加到列表中。这修复了不必要地发生的两件事classy_items

  1. 以前,无论项目是否经典,都会将其添加到列表中,然后仅当它是经典时才更改为其经典值。现在它只增加了优雅物品的价值。
  • items之前: [2, 4, “jacket”, 5, 4]
  • items现在: [2, 4, 5, 4]
  1. 删除了这些语句。这是不必要的,也不是一个好的做法。return print(...)
  2. 用一个简单的函数计算了总的 claassyness,该函数只是对列表求和。sum(...)
  • 现在,这是可能的,因为它不会将任何未使用的字符串添加到列表中。
  • 它还消除了对冗余语句的需求。if