首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Python中将一个数字与修改后的列表的每个组成部分进行比较?

如何在Python中将一个数字与修改后的列表的每个组成部分进行比较?
EN

Stack Overflow用户
提问于 2020-08-28 18:41:21
回答 1查看 68关注 0票数 0

因此,我在这段代码中的主要目标是检查随机生成的数字(s)是否大于随机生成的数字列表中的任何其他组成部分。如果是这种情况,那么应该将检查过的数字添加到标记为“已用”的单个随机生成的数字中,并从列表中退出,然后该过程应该再次开始。在有两个或更多的数字低于单个随机生成的数字的情况下,这两个数字都应该被“标记”并从列表中退出,但只有两个数字中最大的一个应该添加到单个生成的数字中,以便下一次循环。最后,它应该说明需要多少次循环才能使列表中的所有随机数“标记”并使用,或者循环通过而没有任何数字被“标记”。

由于这个解释可能不清楚,我将在这里举一个例子。假设生成的单个数字(s)为0.2,而随机生成的数字列表为(0.2,0.3,0.4,0.5)。该算法首先将s与0.2进行比较,当它相等时,s将变为0.2 + 0.2 = 0.4,0.2将被“标记”并从池中退出,新的循环将开始。在下一个循环中,算法将检查0.3和0.4是否都等于或小于新的s ( 0.4 ),因此两者都将被“标记”,退役,并且s将变为0.2 +0.4= 0.6。在最后一个周期中,0.5将被标记并退役,s将变为0.2 + 0.5 = 0.7,需要3个循环来标记所有数字。

到目前为止,我已经想出了这个(请忽略关于随机数生成的规范)

代码语言:javascript
运行
复制
import random
import numpy as np

for x in range(0, 101):
    s = random.gauss(0.5, 1)
    s = round(s, 2)
    if s < 0:
        s = 0
    if s > 1:
        s = 1
    print("This is S")
    print(s)
    ai = []
    ai_size = 10
    for i in range(ai_size):
        num = float(random.gauss(0.5,1))
        num = round(num, 2)
        if num < 0:
            num = 0  
        if num > 1:
            num = 1
        ai.append(num)

    print("This is the vector of Ai")
    print(ai)
    ai = sorted(ai)
    print("This is the vector numerically ordered")
    print(ai)
    ai_mean = (np.mean(ai))
    ai_var = (np.var(ai))
    print(ai_mean)
    print(ai_var)
    rev = 0
    loop = 0
    for i in ai:
            if s >= i:
                s +=  i
                rev += 1 
                loop += 1
                print("This is evolving S")
                print(s)
            else:
                 break
    print("Loop is over")        
    print("This is the number of elements within the list that are marked")
    print(rev)
    print("This is the number of loops")
    print(loop)
    ai_percentage = rev / ai_size * 100
    print("This is the percentage")
    print(ai_percentage)

这段代码的问题主要是,当在任何给定的循环中有多个应该标记和退出的数字时,它只会在进入下一个循环之前检查第一个数字,这意味着它总是以相同数量的循环和已经标记的数字结束(而在许多情况下,循环的数量应该更少)。它还使S成为所有标记数字的连续和(在前面的示例中,它将执行0.2 + 0.2 + 0.3 + 0.4 + 0.5),而不是保持原始S不变,只添加最高标记数字,正如我之前在示例中所解释的那样。

任何关于这方面的想法或技巧都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-28 19:42:00

所以这个问题有两个部分:

让我们先从概念上解决你提到的连续求和问题。因为我们不想不断地对它们求和,所以我们必须保留两个不同的部分,“基数”和“增量”。我将使用base_s作为基础,使用delta_s作为增量:

代码语言:javascript
运行
复制
import random
import numpy as np

for x in range(0, 101):
    base_s = random.gauss(0.5, 1)
    base_s = round(s, 2)
    if base_s < 0:
        base_s = 0
    if base_s > 1:
        base_s = 1
    delta_s = 0.0
    print("This is S")
    print(base_s + delta_s)

    # ...

    rev = 0
    loop = 0
    for i in ai:
        if base_s + delta_s >= i:
            delta_s = i
            rev += 1
            loop += 1
            print("This is evolving S")
            print(base_s + delta_s)
        else:
            break

    # ...

现在我们已经解决了小部分,让我们关注如何处理同时验证条件的多个元素。首先,python有一个名为filter的内置函数,它允许我们获得验证某些条件的序列的一部分。filter的第一个参数是一个将为每个元素调用的函数,如果返回True,则包含该元素,否则将忽略该元素。list(filter(lambda x: x <= base_s + delta_s, ai))将返回[0.2]list(...)将把它转换回一个列表,因为它返回一种特殊类型的序列,而lambda x: x <= base_s + delta_s只是一种定义函数的内联方式,对于小于或等于s(基加增量)的元素,该函数返回true。

现在让我们把它变成一个有用的函数。它将执行单循环迭代,因此我们将其称为iterate。第一个参数是数字列表,第二个参数是基数S,第三个参数是增量S(默认为0.0)。我们还将使用循环和rev count (默认为1)作为第四个和第五个参数。它将返回剩余的项、最后的s以及循环和转速计数器。

代码语言:javascript
运行
复制
def iterate(items, base_s, delta_s=0.0, loop=0, rev=0):
    # Compute s
    s = base_s + delta_s
    # Get the elements lower or equal to S
    extracted = list(filter(lambda x: x <= s, items))

    # If there are no elements, we don't have to iterate any longer
    if len(extracted) == 0:
        return items, s, loop, rev

    # Remove the lower or equal elements
    items = list(filter(lambda x: x > s, items))
    # Find the biggest  extracted element as this will be the new delta_s
    delta_s = max(extracted)
    # Update loop and rev counters
    loop += 1
    rev += len(extracted)

    # Once everything is updated we can call the same function again to do another loop
    return iterate(items, base_s, delta_s, loop, rev)

我们已经有了我们的函数,当调用一次时,它会根据需要进行任意多次的迭代。这些函数之所以被称为递归函数,是因为它们调用自己。第一个iterate调用将调用第二个,依此类推,当一个调用到达if len(extracted) == 0时,这意味着不需要进行迭代,接下来的调用将一个接一个地返回,以给出最终结果。

它实际上可以变得更短(我保留了更长的时间,以便更容易理解):

代码语言:javascript
运行
复制
def iterate(items, base_s, delta_s=0.0, loop=0, rev=0):
    s = base_s + delta_s
    extracted = list(filter(lambda x: x <= s, items))
    if len(extracted) == 0:
        return items, s, loop, rev
    return iterate(list(filter(lambda x: x > s, items)), base_s, max(extracted), loop + 1, rev + len(extracted))

要使用它来解决您的示例,您可以调用:

代码语言:javascript
运行
复制
remaining_items, s, loop, rev = iterate([0.2, 0.3, 0.4, 0.5], 0.2)

我留下你的练习,把它引入你的代码,如果你发现它有任何问题,请留下评论,我会帮助你的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63632212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档