im试图基于3个pandas df列构建嵌套字典:
数据框:停止 列:'direction'(1-2),'stop_num'(如果方向为1则为1-23,如果方向为2则为100-2300),'name_eng'
我想做的是:
dct = {x:{y:z}表示zip中的x,y,z(stops ['direction'],stops ['name_eng'],stops ['stop_num'])}
我得到的结果确实是一个嵌套的字典,但是由于未知原因,我只得到y:z中的最后一个值,所以字典看起来像:
{1:{1:'aaa'},'2:{100:'bbb'}}
知道我在做什么错吗? 我需要的是一个嵌套的字典,每个方向都有两个字典。
谢谢!
答案 0 :(得分:0)
想象一下您的专栏是:
1 a 1a
1 b 1b
2 a 2a
2 b 2b
现在,尝试您的代码:
>>> {x: {y:z} for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b'])}
{1: {'b': '1b'}, 2: {'b': '2b'}}
您在元组上有一个循环:(1, 'a', '1a'), (1, 'b', '1b'), (2, 'a', '2a'), (2, 'b', '2b')
。
元组的第一个元素是字典的“主”键。因此,字典在第一个元组之后是{1: {'a':'1a'}}
。
然后是(1, 'b', '1b')
。主键1
的值将被覆盖,并且字典变为:{1: {'b':'1b'}}
。
下一步是:{1: {'b':'1b'}, 2: {'a': '2a'}}
和{1: {'b': '1b'}, 2: {'b': '2b'}}
为避免覆盖,可以执行以下操作:
>>> d = {}
>>> for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']):
... d.setdefault(x, {}).update({y:z})
...
>>> d
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
这个想法是为每个新的主键(setdefault(..., {})
)创建一个新的字典,并更新与主键(update({y:z})
)关联的字典。
如果您想理解dict,则可以使用该方法:
>>> {x: {y:z for k, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']) if k==x} for x in set([1,1,2,2])}
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
但是它的效率远不及for
循环,因为您在第一列上循环一次以获取主键,然后在每个主键上再次遍历所有行。