如何替换列表中的值

huangapple go评论59阅读模式
英文:

How to replace list values

问题

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)):
            if self.items[i] == "bowtie":
                self.items[i] = 4
                print("Item Added")
                return

            if self.items[i] == "tophat":
                self.items[i] = 2
                print("Item Added")
                return

            if self.items[i] == "monocle":
                self.items[i] = 5
                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())

上述代码对您提供的Python类进行了一些修复,使其能够正确更新项目的值。修复包括更改self.add_item[0]self.add_item,以正确遍历项目,以及更改print语句的引号以使其与Python的语法匹配。希望这有助于您解决问题。

英文:
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())

The requirements is that classy items must be stored in a string as input, then string is added to
the list, and that there is a method that calculates the classiness.

The output of the current code is:

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

Currently, in my debugging, I can see that it adds the value 'tophat' and then it replaces it with the value 2
but when it comes to the 'bowtie' or 'monocle' it adds them to the list and then doesn't replace the values
I would like to know why it doesn't change the value any other time the method is called

答案1

得分: 1

Problem

当你使用 for i in range(len(self.add_item[0])): 时,你正在枚举i从0到存储在self.add_item中的字符串的第一个字符的长度,这将始终为1。所以i将从0开始,每次结束之前都会在1之前结束(因此i只会是0)。

因此,第一项 "tophat" 有效,因为当你使用 append 将 tophat 添加到列表时,它看起来像这样:["tophat"](列表只包含 "tophat" 在索引0处)。所以 self.items[i] 处的项目(即 self.items[0])是 tophat,所以 if self.items[i] == "tophat": 将评估为 true。

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

以下是代码本身中正在发生的情况:

第一次调用

me.addItem("tophat")
# self.items 变成 ["tophat"]
# self.items[i](其中i为0)等于 "tophat"
# self.items[i] 变成2
# self.items 现在是 ["tophat"]
> "Item Added"

第二次调用

me.addItem("bowtie")
# self.items 变成 [2, "bowtie"]
# self.items[i](其中i为0)不等于任何字符串,因为 self.items[0] 是2
# self.items 仍然是 [2, "bowtie"]
> "NO item added"

第三次调用

me.addItem("jacket")
# self.items 变成 [2, "bowtie", "jacket"]
# self.items[i](其中i为0)不等于任何字符串,因为 self.items[0] 是2
# self.items 仍然是 [2, "bowtie", "jacket"]
> "NO item added"

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

Solution

我认为你打算做的是检查最近添加的项目是否等于你的一些高级字符串之一。如果去掉 for 循环,只需检查最后一个项目(使用 self.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

Solution Continued

为了进一步简化代码,我编写了另一个版本,它产生相同的结果,同时减少了后续可能出现混淆错误的机会。

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 检查新项目是否存在于 classy_items 中,如果是,则将其值添加到列表中。这修复了两个不必要的事情:

  1. 以前无论项目是否高雅,都将其添加到列表中,然后仅在项目是高雅的情况下将其更改为其高雅的值。现在它只会添加高雅的项目的值。
  • items 在之前:[2, 4, "jacket", 5, 4]
  • items 现在:[2, 4, 5, 4]
  1. 删除了 return print(...) 语句。这是不必要的,也不是一个好的实践。
  2. 使用一个简单的 sum(...) 函数计算总高雅,它只是对列表进行求和。
  • 这现在是可能的,因为它不会将任何未使用的字符串添加到列表中。
  • 它还消除了多余的 if 语句。
英文:

Problem

When you do for i in range(len(self.add_item[0])): you are enumerating i from 0 to the length of the first character of the string stored in self.add_item, which will always be 1. So i will start at 0 and end before 1 every time (So i will only ever be 0).

So the first item "tophat" works because when you add tophat to the list with append it looks like this: ["tophat"] (the list only contains "tophat" at index 0). So the item at self.items[i] (i.e. self.items[0] is tophat, so if self.items[i] == "tophat": will evaluate to true.

The next line in the if block replaces the value of "tophat" with 2 in the list. So for every subsequent call to addItem all the if statements that compare self.items[i] are really just comparing the new first value (2) to the other strings ("bowtie", "tophat", etc).

Here is what is going on in the code itself

First call

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"

Second call

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"

Third call

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"

... and so on for each subsequent call to addItem.


Solution

What I think you intended to do is check if the most recently added item is equal to one of your classy strings. If you get rid of the for loop and just check the last item (using self.items[-1]) you will be able to just replace the new item with its classyness value.

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")

The result using this method would be

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

Solution Continued

To further simplify the code, I put together a different version that produces the same results while also reducing the chances of confusing errors later down the line.

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 stores all the classy items and their classyness values in a key-value pair dictionary.

addItem checks if the new item exists in in classy_items and adds its value to the list if so. This fixes two things that were happening unnecessarily

  1. Previously the item was added to the list regardless of if it was classy or not, and then changed to its classyness value only if it was classy. Now it only adds the value of classy items.
  • items before: [2, 4, "jacket", 5, 4]
  • items now: [2, 4, 5, 4]
  1. Removed the return print(...) statements. This was unnecessary and not a good practice.
  2. Calculated the total claassyness with a simple sum(...) function which just sums the list.
  • This is now possible because it is not adding any unused strings to the list.
  • It also removes the need for redundant if statements.

huangapple
  • 本文由 发表于 2023年3月7日 10:18:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定