简体   繁体   English

递归遍历列表并与值进行比较(python)

[英]Recursively going through list and compare with a value (python)

The task is to go through a list, compare it with a value and then return the amount of times the value occurred.任务是通过一个列表对go,将其与一个值进行比较,然后返回该值出现的次数。 The comparison works and when I find the matching value I want to save it in a list.比较有效,当我找到匹配值时,我想将其保存在列表中。 Then I want to get the length of that list.然后我想得到那个列表的长度。 The problem is that every time i call on the function again the list resets, how do I avoid that?问题是每次我再次调用 function 时,列表都会重置,我该如何避免呢?

    def count_occurences(values, value):
        matched_values = []
        if values:
            if values[0] == value:
                matched_values.append(values[0])
                count_occurences(values[1:], value)
            else:
                count_occurences(values[1:], value)
        else:
            return 0
        return len(matched_values)
    count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")

In this case the expected output would be: 2.在这种情况下,预期的 output 将是:2。

As @juanpa.arrivillaga stated in comments, you are initializing matched_values to empty list each call, so you are returning nothing effectively.正如@juanpa.arrivillaga 在评论中所说,您正在将matched_values初始化为每次调用都清空列表,因此您没有有效地返回任何内容。

The script can be simplified, for example:脚本可以简化,例如:

def count_occurences(values, value):
    if values:
        return (values[0] == value) + count_occurences(values[1:], value)
    return 0

n = count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")
print(n)

Prints:印刷:

2

You can solve your immediate problem by simply moving the matched_values assignment outside of the function, as shown below.您可以通过简单地将matched_values分配移到function 之外来解决您的直接问题,如下所示。

matched_values = []

def count_occurences(values, value):
    if values:
        if values[0] == value:
            matched_values.append(values[0])
            count_occurences(values[1:], value)
        else:
            count_occurences(values[1:], value)
    else:
        return 0
    return len(matched_values)
count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")

However, this code really raises more questions than it answers.然而,这段代码确实提出了比它回答的问题更多的问题。 Presumably you are doing this as a learning exercise as you can easily do this without a special function or recursion.大概您将其作为学习练习进行,因为您无需特殊的 function 或递归即可轻松完成此操作。 So bearing that in mind I'd ask you:所以考虑到这一点,我会问你:

  • What is the point of matched_values ? matched_values的意义何在? By definition it will just be the same entry repeatedly so it adds no information over just knowing the number of matches根据定义,它只是重复的同一个条目,因此它不会添加任何信息而不是只知道匹配的数量
  • Recursion is a common pattern in functional programming but your function's primary purpose is to mutate a variable outside the function - this is called a side effect and is generally considered undesireable in functional style递归是函数式编程中的一种常见模式,但您的函数的主要目的是改变 function 之外的变量 - 这被称为副作用,通常被认为在函数式风格中是不受欢迎的

With those in mind, you might consider something like this which does away with the list and involves no mutation and no side effects.考虑到这些,您可能会考虑这样的事情,它消除了列表并且不涉及突变和副作用。

def count_occurences(values, value):
    if values:
        if values[0] == value:
            return 1 + count_occurences(values[1:], value)
        else:
            return count_occurences(values[1:], value)
    else:
        return 0

(which is essentially identical to the simplification suggested by Andrej Kesely above) (这与上面 Andrej Kesely 建议的简化基本相同)

 matched_values = [] 

 def count_occurences(values, value, matched_values):
            if values:
                if values[0] == value:
                    matched_values.append(values[0])
                    count_occurences(values[1:], value, matched_values)
                else:
                    count_occurences(values[1:], value, matched_values)
            else:
                return 0
            return len(matched_values, matched_values)

 count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two", matched_values)

The list was reset at every call of the recursive function count_occurences because you recreated the list at the beginning of the function with this line: matched_values = [] .每次调用递归 function count_occurences时都会重置该列表,因为您在 function 的开头使用以下行重新创建了该列表: matched_values = [] This creates a new variable matched_values that points to a new location in memory and does not have access to what was found by the previous round.这将创建一个新变量matched_values ,它指向memory 中的新位置,并且无法访问上一轮找到的内容。

Initializing this empty list before the function is called ensures that the same location in memory will be accessed every time the function runs.在调用 function 之前初始化此空列表可确保每次 function 运行时都会访问 memory 中的相同位置。 Every recursive call will operate on the same list, and you won't lose information.每个递归调用都将在同一个列表上运行,并且您不会丢失信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM