我正在尝试将一些数据转换为嵌套字典,其中有一个通用的State键,然后是与数字匹配的特定Area键(如下所示)。
为了使数据更好地形成,我有一个痛苦的三重循环,如下所示。但是,它无法正常工作,因为它只保存每个州/地区的最后一个号码。我试图调整此代码,但没有看到在哪里修复我的迭代,使其正确循环遍历每个迭代器并相应地放置增长数字。我想要获得的输出与实际输出相比低于 - 虽然没有错误消息,但输出不是我的目标。
感谢您对此提供的帮助,并且好奇如果在字典中有字典时这是一种非常低效(或没有问题)的迭代方式。
state=['NJ', 'NY', 'TX', 'CA', 'OH']
area=['North','South']
growth = [['State', 'North', 'South'],
['NJ', '5.09', '3'],
['NY', '0', '1',],
['TX', '8','5.54'],
['CA', '6', '1'],
['OH', '7.77', '5']]
nested_dict={}
for i in range(1,len(growth)):
nested_dict[growth[i][0]]=dict()
for i in range(0,len(state)):
for j in range(0,len(area)):
for k in range(1,len(growth[0])):
nested_dict[state[i]][area[j]]=float(growth[i+1][k])
预期产出:
{'CA': {'North': 6.0, 'South': 1.0},
'NJ': {'North': 5.09, 'South': 3.0},
'NY': {'North': 0.0, 'South': 1.0},
'OH': {'North': 7.77, 'South': 5.0},
'TX': {'North': 8.0, 'South': 5.54}}
输出错误:
{'CA': {'North': 1.0, 'South': 1.0},
'NJ': {'North': 3.0, 'South': 3.0},
'NY': {'North': 1.0, 'South': 1.0},
'OH': {'North': 5.0, 'South': 5.0},
'TX': {'North': 5.54, 'South': 5.54}}
编辑上述内容以反映评论
答案 0 :(得分:1)
您要将growth
行中的第2和第3个值分配给所有state
和area
配对,并使用最里面的循环:
for k in range(1,len(growth[0])):
所以你最终分配了两次:
# first iteration
i = 0 # state: NJ
j = 0 # area: North
k = 1 # second column in growth
nested_dict[state[0]][area[0]] = float(growth[0+1][1])
# nested_dict['NJ']['North'] = float(['NJ', '5.09', '3'][1] == '5.09')
# second iteration
i = 0 # state: NJ
j = 0 # area: North
k = 2 # third column in growth
nested_dict[state[0]][area[0]] = float(growth[0+1][2])
# nested_dict['NJ']['North'] = float(['NJ', '5.09', '3'][2] == '3')
请注意i
和j
未改变的方式!
你根本不需要第三个循环,你已经选择了你的州和地区;只需从表中选择正确的值,使用area
索引加1来映射到右列:
for i in range(len(state)):
for j in range(len(area)):
nested_dict[state[i]][area[j]] = float(growth[i + 1][j + 1])
# instead of k ^^^^^
现在,使用索引单字母索引会使您难以遵循代码。你应该真正了解这里的enumerate()
function,以生成索引:
for row, state_name in enumerate(state, 1): # starting at row 1
for col, area_name in enumerate(area, 1): # starting at column 1
nested_dict[state_name][area_name] = float(growth[row][col])
通过state
直接循环,并使用enumerate()
添加从1开始的索引,您将获得州名('NJ'
)和指向growth
(1
)的正确索引。 area
列表也是如此('North'
和1
,或'South'
和2
)。
但是,您已经在growth
矩阵中拥有了所有行名和列名,因此您可以直接使用它生成所有词典:
area_names = growth[0][1:]
nested_dict = {
state: {area: float(value) for area, value in zip(area_names, row)}
for state, *row in growth[1:]
}
zip()
function将区域名称(位于growth
的第一行)与每列的值(存储在row
中)放在一起,第一个值转移到{ {1}})。
注意state
循环; Python将每个列表从for state, *row in ..
解压缩为两个变量;第一个值存储在growth
中,由于state
以row
为前缀,所有剩余值都存储在*
中:
row
这真的是你所需要的:
>>> state, *row = ['NJ', '5.09', '3']
>>> state
'NJ'
>>> row
['5.09', '3']
最后但并非最不重要的是,如果所有这些数据来自CSV文件,您可能应该使用csv
module代替:
>>> area_names = growth[0][1:]
>>> nested_dict = {
... state: {area: float(value) for area, value in zip(area_names, row)}
... for state, *row in growth[1:]
... }
{'NJ': {'North': 5.09, 'South': 3.0}, 'NY': {'North': 0.0, 'South': 1.0}, 'TX': {'North': 8.0, 'South': 5.54}, 'CA': {'North': 6.0, 'South': 1.0}, 'OH': {'North': 7.77, 'South': 5.0}}
>>> from pprint import pprint
>>> pprint(_)
{'CA': {'North': 6.0, 'South': 1.0},
'NJ': {'North': 5.09, 'South': 3.0},
'NY': {'North': 0.0, 'South': 1.0},
'OH': {'North': 7.77, 'South': 5.0},
'TX': {'North': 8.0, 'South': 5.54}}
import csv
nested_dict = {}
with open(somefile, 'r', newline='') as f:
reader = csv.DictReader(f)
for row in reader:
state = row.pop('State')
nested_dict[state] = {k: float(v) for k, v in row.items()}
对象将CSV文件的第一行作为列名,并为每行生成一个字典。如果您的州列使用名称旁边的引号,您甚至可以使用DictReader()
让模块自动将未引用的任何内容转换为quoting=csv.QUOTE_NONNUMERIC
值。
答案 1 :(得分:1)
除非我遗漏了一些重要内容,否则你不需要任何嵌套循环,也不需要其他两个列表。单个(嵌套)字典理解就足够了。
@Override
public void onBackPressed() {
if (isViewD_Visible) {
// show View-C
isViewD_Visible = false;
}else {
// ...
}
}
(假设result = {st: {"North": float(n), "South": float(s)}
for (st, n, s) in growth[1:]}
print(result)
# {'OH': {'North': 7.77, 'South': 5.0}, 'TX': {'North': 8.0, 'South': 5.54},
# 'NJ': {'North': 5.09, 'South': 3.0}, 'NY': {'North': 0.0, 'South': 1.0},
# 'CA': {'North': 6.0, 'South': 1.0}}
列表包含的每个州不超过一次,并且第一,第二和第三项始终是州,北和南值,按此顺序。)