我试图建立一个基于3个pandas df列的嵌套字典:
dataframe:停止列:'direction'(1-2),'stop_num'(如果方向为1则为1-23,如果方向为2则为100-2300),'name_eng'
我想要做的是:
zip中的x,y,z的dct = {x:{y:z}(停止['方向'],停止['name_eng'],停止['stop_num'])}
我得到的结果确实是一个嵌套字典,但由于未知原因我只得到y:z中的最后一个值,所以字典看起来像:
{1:{1:'aaa'},'2:{100:'bbb'}}
知道我做错了什么吗?我需要的是一个嵌套字典,每个方向都有两个字典。
谢谢!
想象一下你的专栏是:
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')
。
元组的第一个元素是字典的“主”键。因此,在第一个元组之后,dict是{1: {'a':'1a'}}
。
然后是(1, 'b', '1b')
。主键1
的值被覆盖,dict变为:{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(..., {})
)创建一个新的dict,并更新与主键(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
循环,因为你在第一列上循环一次以获得主键,然后在所有行上循环,为每个主键循环。