我试图使用嵌套的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可能属于意外类型(int,str),表示c没有充分定义为整数。我不愿提出有关PyCharm的问题,因为我可能缺少一些简单的东西。有人看到我想念的东西吗?
答案 0 :(得分:2)
关于 PyCharm 警告(问题全在)
尽管突出显示了2 nd 索引( c ),让用户认为它是问题所在, 完全不是这个问题。
通常,列表是齐整的容器,这意味着它们包含相同类型的元素。
PyCharm 将 v_f_vector 评估为 int s列表列表 >(因此v_f_vector[b][c]
为 int )。尝试为其分配一个字符串可能会破坏列表的同质性,因此出现警告。
尝试为其分配伪值(例如0.01f
,()
, []
,...),警告文本将更改,例如在下图中:
作为一种快速(又肮脏)的解决方法,如果列表将包含字符串,则可以执行以下操作:
v_f_vector = [["", "", "", ""], ["", "", "", "", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""]]
关于导致此问题的代码
声明具有特定内容的列表,然后返回并更改该内容(基于另一个(类似结构的)列表)是违反直觉的。
您的(最终)目标可以通过一行行代码(最 Python ic形式)实现,其中包括列表理解(选中[Python 3]: 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']]
注意:您的代码也可以进行修改,但是我建议使用推荐的变体。
答案 1 :(得分:1)
我认为警告来自您用字符串替换整数值的事实。当我尝试使用v_f_vector
而不是'0'
来实例化0
时,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
。
答案 2 :(得分:0)
您应该使用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])
抱歉,这并不是您所要回答的问题的真正答案,但这是为了使读者更易读,枚举将始终为您提供索引和值,或者如果它是字典,则将为您提供键和值。 / p>
可能还值得注意的是,将列表嵌套在字典中,然后为每个列表指定一个特定的键,以便您可以访问它们,这具有更大的人类可读性。
值得思考的食物
为了增加清晰度,假设您有4个向量,向量a,b,x和y。您可以将他们各自的列表中的每一个都放在自己的字典键中,然后使用其键进行访问。