【问题标题】:Counter in range() not recognized as integerrange() 中的计数器无法识别为整数
【发布时间】:2019-03-26 20:25:43
【问题描述】:

我正在尝试使用嵌套的 for 循环遍历对每个列表的每个元素进行操作的列表列表。我从 PyCharm 收到警告,第二个 for 循环中的计数器类型不一定是整数,尽管它是从范围值派生的。代码正确执行,为什么会出现警告?

def get_vote_fraction(cl_count, ag_vector):
    v_f_vector = [[0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0]]
    for b in range(0, len(v_f_vector)):
        for c in range(0, len(v_f_vector[b])):
            v_f_vector[b][c] = f"{(ag_vector[b][c] / cl_count): .2F}"
    return v_f_vector


aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
class_count = 10
vote_fraction = get_vote_fraction(class_count, aggregated_vector)
print(vote_fraction)

正如预期的那样,输出是 [['0.00', '0.80', '0.00', '0.60'], ['0.00', '0.10', '0.00', '0.00', '0.00', '0.00 '、'0.90'、'0.00']、['0.00'、'0.00'、'1.00'、'0.00']、['0.00'、'1.00'、'0.00'、'0.00'、'0.00'] ]

我收到一条警告,指出 v_f_vector[b][c] 中的 c 可能是 Unexpected type(s) (int, str),这表明 c 没有充分定义为整数。我很犹豫提出 PyCharm 的问题,因为我可能遗漏了一些简单的东西。有人看到我错过了什么吗?

【问题讨论】:

  • c (你的范围变量)确实是一个整数;如果我没看错,投诉是关于v_f_vector[b][c](列表元素)。
  • 您可以创建工单。根据我的经验,Pycharm 无法解决此类问题是很常见的。只要知道如果它打扰您,您可以在您的设置中将警告变成弱警告。
  • 我测试这个时没有警告

标签: python types pycharm warnings


【解决方案1】:

关于 PyCharm 警告(问题的全部内容)

虽然第2个nd索引(c)被高亮,让用户认为是问题所在, 根本不是这样

通常,列表是同类容器,这意味着它们包含相同类型的元素。
PyCharmv_f_vector 评估为 int 的列表 (因此v_f_vector[b][c] 是一个int)。尝试为其分配 string 会破坏列表的同质性,因此会发出警告。
尝试为其分配虚拟值(例如0.01f()[]、...),警告文本会发生变化,如下图所示:

作为一种快速(且肮脏)的解决方法,如果列表将包含字符串,您可以执行以下操作:

v_f_vector = [["", "", "", ""], ["", "", "", "", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""]]

关于导致此问题的代码

声明具有特定内容的列表,然后返回并更改该内容(基于另一个(类似结构的)列表)是违反直觉的。

您的(最终)目标,可以通过 一行 行代码(最Pythonic 形式)实现,其中包含一个列表理解(检查[Python 3.Docs]: List Comprehensions)。由于您的列表嵌套级别为 2,因此理解也是:

>>> aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
>>> class_count = 10
>>>
>>> vote_fraction = [[f"{(item1 / class_count): .2F}" for item1 in item0] for item0 in aggregated_vector]
>>> print(vote_fraction)
[[' 0.00', ' 0.80', ' 0.00', ' 0.60'], [' 0.00', ' 0.10', ' 0.00', ' 0.00', ' 0.00', ' 0.00', ' 0.90', ' 0.00'], [' 0.00', ' 0.00', ' 1.00', ' 0.00'], [' 0.00', ' 1.00', ' 0.00', ' 0.00', ' 0.00']]
>>>
>>> # Or, if you REALLY need to have a function
...
>>> def get_vote_fraction(cl_count, ag_vector):
...     return [[f"{(item1 / cl_count): .2F}" for item1 in item0] for item0 in ag_vector]
...
>>>
>>> print(get_vote_fraction(class_count, aggregated_vector))
[[' 0.00', ' 0.80', ' 0.00', ' 0.60'], [' 0.00', ' 0.10', ' 0.00', ' 0.00', ' 0.00', ' 0.00', ' 0.90', ' 0.00'], [' 0.00', ' 0.00', ' 1.00', ' 0.00'], [' 0.00', ' 1.00', ' 0.00', ' 0.00', ' 0.00']]

注意:您的代码也可以调整,但我建议使用推荐的变体。

【讨论】:

【解决方案2】:

我认为警告来自您将整数值替换为字符串这一事实。当我尝试用'0' 而不是0 来实例化v_f_vector 时,PyCharm 没有显示任何警告:

v_f_vector = [['0', '0', '0', '0'], ['0', '0', '0', '0', '0', '0', '0', '0'], ['0', '0', '0', '0'], ['0', '0', '0', '0', '0']]

但是,这可能不是解决问题的最佳方法。我建议对您的代码进行这样的重构:

def get_vote_fraction(cl_count, ag_vector):
    v_f_vector = []
    for b in range(0, len(ag_vector)):
        v_f_vector.append([])
        for c in range(0, len(ag_vector[b])):
            v_f_vector[b].append(f"{(ag_vector[b][c] / cl_count): .2F}")
    return v_f_vector


aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
class_count = 10
vote_fraction = get_vote_fraction(class_count, aggregated_vector)
print(vote_fraction)

它将允许您更改aggregated_vector,而无需将这些更改反映到实例化的v_f_vector

【讨论】:

  • 感谢您对我的问题给出最清晰的回答。我知道枚举和列表推导等选项!我提供的代码 sn-p 是我可以设计的最简单的代码,它会产生警告情况,这确实与您描述的完全一样。 (我也喜欢你的重构建议!)
【解决方案3】:

你应该使用enumerate()

例子:

iterable = [1,2,3,4]
for i, v in enumerate(iterable):
    print(i,v)

预期输出

0 1
1 2
2 3
3 4

代替

for x in range(0, len(iterable)):
    print(x, iterable[x])

抱歉,这并不是您问题的真正答案,但这样更易于阅读,而且 enumerate 将始终为您提供索引和值,或者如果它是字典,则为键和值。

还可能值得注意的是,将列表嵌套在字典中,然后为每个列表指定一个特定的键,以便您可以访问它们,这更便于人类阅读。

值得深思

为了清楚起见,假设您有 4 个向量,向量 a、b、x 和 y。您可以将它们各自的列表放在各自的字典键中,然后使用它们的键访问它们。

【讨论】:

  • 如果你明白这不是一个真正的答案,为什么不添加评论而不是答案?
  • 因为在可迭代对象的 len 中使用范围是很糟糕的做法。评论无法像我通过示例所做的那样解释这一点。
猜你喜欢
  • 2018-08-08
  • 2021-10-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 2022-01-16
相关资源
最近更新 更多