【问题标题】:Need take a value list from a dictionary, and subtract that value from a total number of values需要从字典中获取值列表,然后从值的总数中减去该值
【发布时间】:2023-03-28 10:53:01
【问题描述】:

我知道标题可能令人困惑,所以请允许我解释一下。

我从一个看起来像 L = [21.123, 22.123, 23.123, 21.123] 的列表中获取输入 我删除了小数,并将列表从高到低排序。我还把它改成了一个字典,看起来像 newlist = {23: 1, 22: 1, 21: 2}

我需要做的是列出我可以做的键和值的列表。这给了我两个列表,[23, 22, 21][1, 1, 2] 一个用于值,一个用于事件。我需要将我的出现列表转换为与相应键相同或低于它的出现次数。

我希望我的列表看起来像 [23, 22, 21](这很容易做到)和 [4, 3, 2],因为其中 4 次是 23 秒或更短,3 次是 22 秒或更短,还有 2 次时间为 21 秒或更短。

我很确定我需要一个 for 循环来遍历每个频率值,并将该值更改为输入到列表中的总次数,然后减去任何超过它的值。我不知道该怎么做,所以任何帮助将不胜感激。

【问题讨论】:

  • 你尝试过什么,到底有什么问题?
  • 提示:使用累积和
  • 对于您的第一个问题,请尝试使用标准库集合模块 collections.Counter(map(int, [21.123, 22.123, 23.123, 21.123])) 中的 Counter。在此处提问时,请避免同时提出多个问题,并包含您的尽力而为的代码。即使您的代码不起作用,它也可以帮助我们准确了解您想要做什么。
  • 我试图弄清楚如何计算出现次数多于相应的键,所以如果我在 valuelist 中对应于 22 出现次数的值上,我不不知道如何计算数字 22-min 值出现的次数,并排除 1 次 23 出现的次数。然后从总次数中减去超过对应键的数量,即4(总次数)减1(一次> 22秒)
  • 老实说,很难说出[4, 3, 2] 是什么。 “4 次是 23 秒或更短” 到底是什么意思?

标签: python python-3.x list dictionary for-loop


【解决方案1】:

您需要一个字典,其中对于数据中的每个项目,键是舍入值 (int(item)),值是小于或等于舍入值的项目数。

字典推导(结合列表推导)可以做到这一点:

data = [21.123, 22.123, 23.123, 21.123]

aggregate = {
    item: len([n for n in data if int(n) <= item])
    for item in set(map(int, data))
}

print(aggregate)  # -> {21: 2, 22: 3, 23: 4}

这是编写这样一个循环的单语句形式:

aggregate = {}
for item in set(map(int, data)):
    aggregate[item] = len([n for n in data if int(n) <= item])
}

使用set() 使列表独一无二。这样循环只会在必要时运行。

【讨论】:

  • 循环中的 len([n for n in data if int(n) &lt;= item]) 似乎有点矫枉过正。当然,它可以工作,但是您通过计数的累积求和执行了比必要更多的求和。无论如何,更干净的 IMO 至少要避免创建列表,例如 sum(int(n) &lt;= item for n in data)
  • 公平点,我同意。我认为 “计算小于 X 的项目数” 的想法可能对 OP 以列表理解的形式更直观。
【解决方案2】:

这是一个实用的解决方案。稍微棘手的部分是反向累积和,它可以将一个反转的元组提供给itertools.accumulate,然后反转结果。

from collections import Counter
from itertools import accumulate
from operator import itemgetter

L = [21.123, 22.123, 23.123, 21.123]

c = Counter(map(int, L))                       # Counter({21: 2, 22: 1, 23: 1})
counter = sorted(c.items(), reverse=True)      # [(23, 1), (22, 1), (21, 2)]
keys, counts = zip(*counter)                   # ((23, 22, 21), (1, 1, 2))

cumsum = list(accumulate(counts[::-1]))[::-1]  # [4, 3, 2]

您想要的结果存储在keyscumsum

print(keys)

(23, 22, 21)

print(cumsum)

[4, 3, 2]

【讨论】:

  • 我喜欢这个。所有的反转都有点令人困惑,但更好的变量名可能会有所帮助。还可能要注意keyscumsum 持有他想要的两个列表。
【解决方案3】:

假设您从 [21.123, 22.123, 23.123, 21.123] 中正确获取计数,一个带有 运行总和的简单嵌套循环 可以完成剩下的工作:

from collections import Counter

newlist = {23: 1, 22: 1, 21: 2}

counts = Counter()
for k in newlist:
    for v in newlist:
        if v <= k:
            counts[k] += newlist[v]

print(counts)
# Counter({23: 4, 22: 3, 21: 2})

您也可以使用itertools.product() 将双循环压缩为一个:

from itertools import product
from collections import Counter

newlist = {23: 1, 22: 1, 21: 2}

counts = Counter()
for k, v in product(newlist, repeat=2):
    if v <= k:
        counts[k] += newlist[v]

print(counts)
# Counter({23: 4, 22: 3, 21: 2})

上面将计数存储在collections.Counter()中,您可以通过调用list(counts.values())获取[4, 3, 2]

【讨论】:

    【解决方案4】:

    我找到了自己的解决方案,看起来相对简单。代码看起来像

    counter = 0
    print(valuelist)
    for i in valuelist:
        print(int(solves - counter))
        counter = counter + i
        redonevalues.append(solves - counter + 1)
    

    它采用我的值,转到第一个值,将出现次数添加到 counter,从解决方案中减去 counter,然后加 1 以使其均匀

    【讨论】:

    • 我完全不清楚这段代码的作用。 redonevalues 是什么? solves 是什么? valuelist 是什么?为什么solves - counter + 1 会产生任何意义?
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    相关资源
    最近更新 更多