将列表更改为字典

时间:2016-05-29 18:34:55

标签: python list dictionary key-value-store

如何更改这样的列表:

[[0, 'Ealing Broadway', 103.89],
 [0, 'Notting Hill Gate', 103.89],
 [0, 'Mile End', 103.89],
 [1, 'Ealing Broadway', 59.089999999999996],
 [2, 'Notting Hill Gate', 40.279999999999994],
 [3, 'Mile End', 68.86999999999999]]

这样的词典
{0:{'length':103.89,'interchange':['Ealing Broadway','Notting Hill Gate','Mile End']},
1:{'length':59.089999999999996,'interchange':['Ealing Broadway']},
2:{'length':40.279999999999994,'interchange':['Notting Hill Gate']},
3:{'length':68.86999999999999,'interchange':['Mile End']}}

由于

I am trying to start with:

d2 = defaultdict(list)
for k, v in all_info:
    d2[k].append(v)

with_length=dict((k,list(v)) for k,v in d2.iteritems())
with_length

但它不起作用,我正在努力从哪里开始。

5 个答案:

答案 0 :(得分:0)

以下是如何执行此操作的具体示例:

l = [[0, 'Ealing Broadway', 103.89],
     [0, 'Notting Hill Gate', 103.89],
     [0, 'Mile End', 103.89],
     [1, 'Ealing Broadway', 59.089999999999996],
     [2, 'Notting Hill Gate', 40.279999999999994],
     [3, 'Mile End', 68.86999999999999]]

d = {}

for pair in l:
    if pair[0] not in d.keys():
        d[pair[0]] = { 'interchange': [] }

    d[pair[0]]['length'] = pair[2]
    d[pair[0]]['interchange'].append(pair[1])

这假设您要在向d['length']添加元素时覆盖d[0]

答案 1 :(得分:0)

Majora的类似答案,但首先使用groupby。没有错误的查找,但可能需要预先排序。

from itertools import groupby

lst = [[0, 'Ealing Broadway', 103.89],
    [0, 'Notting Hill Gate', 103.89],
    [0, 'Mile End', 103.89],
    [1, 'Ealing Broadway', 59.089999999999996],
    [2, 'Notting Hill Gate', 40.279999999999994],
    [3, 'Mile End', 68.86999999999999]]

new_list = []
for key, group in groupby(lst, lambda x: x[0]):
    new_list.append(list(group))

main_dict = {}
for item in new_list:
    main_dict[item[0][0]] = {'length': item[0][2], 'interchange': [stn[1] for stn in item]}

答案 2 :(得分:0)

b = {}
for i in a:
    if b.has_key(i[0]):
        b[i[0]]['interchange'].append(i[1])
    else:
        b[i[0]] = {'length': i[2], 'interchange': [i[1]]}

答案 3 :(得分:0)

这是一种需要两次通过的方法。它具有易于理解的优点。

while True:
    print('Hello world')

输出

import pprint

if __name__ == '__main__':
    rows = [
        [0, 'Ealing Broadway', 103.89],
        [0, 'Notting Hill Gate', 103.89],
        [0, 'Mile End', 103.89],
        [1, 'Ealing Broadway', 59.089999999999996],
        [2, 'Notting Hill Gate', 40.279999999999994],
        [3, 'Mile End', 68.86999999999999]]

    print('First Pass')
    d = {}
    for key, interchange, length in rows:
        inner_dict = d.setdefault((key, length), {})
        interchanges = inner_dict.setdefault('interchange', [])
        interchanges.append(interchange)

    pprint.pprint(d)

    print('=' * 72)
    print('Second Pass')
    d2 = {}
    for (key, length), v in d.items():
        v['length'] = length
        d2[key] = v

    pprint.pprint(d2)

讨论

  • 在第一遍中,我使用第一列和最后一列作为字典的键。此字典的值是另一个字典(First Pass {(0, 103.89): {'interchange': ['Ealing Broadway', 'Notting Hill Gate', 'Mile End']}, (1, 59.089999999999996): {'interchange': ['Ealing Broadway']}, (2, 40.279999999999994): {'interchange': ['Notting Hill Gate']}, (3, 68.86999999999999): {'interchange': ['Mile End']}} ======================================================================== Second Pass {0: {'interchange': ['Ealing Broadway', 'Notting Hill Gate', 'Mile End'], 'length': 103.89}, 1: {'interchange': ['Ealing Broadway'], 'length': 59.089999999999996}, 2: {'interchange': ['Notting Hill Gate'], 'length': 40.279999999999994}, 3: {'interchange': ['Mile End'], 'length': 68.86999999999999}}
  • 在第二遍中,我将键和值调整为最终形式。
  • 这个解决方案可能不是最有效或最优雅的,但我希望它很容易理解

答案 4 :(得分:0)

请将我的答案视为Pandas(功能强大的Python数据分析工具包)模块方法的演示。

我很确定你是否想要处理大量数据快速 - pandas是你的工具......

import pandas as pd

data = [[0, 'Ealing Broadway', 103.89],
        [0, 'Notting Hill Gate', 103.89],
        [0, 'Mile End', 103.89],
        [1, 'Ealing Broadway', 59.089999999999996],
        [2, 'Notting Hill Gate', 40.279999999999994],
        [3, 'Mile End', 68.86999999999999]
       ]

# create pandas DF
df = pd.DataFrame(data, columns=['route','interchange','length'])

原创DF:

In [235]: df
Out[235]:
   route        interchange  length
0      0    Ealing Broadway  103.89
1      0  Notting Hill Gate  103.89
2      0           Mile End  103.89
3      1    Ealing Broadway   59.09
4      2  Notting Hill Gate   40.28
5      3           Mile End   68.87

让我们对数据进行分组:

In [239]: df.groupby(['route','length'])['interchange'].apply(lambda x: x.tolist()).reset_index()
Out[239]:
   route  length                                     interchange
0      0  103.89  [Ealing Broadway, Notting Hill Gate, Mile End]
1      1   59.09                               [Ealing Broadway]
2      2   40.28                             [Notting Hill Gate]
3      3   68.87                                      [Mile End]

我们也可以将其转换为dicts列表:

In [240]: df.groupby(['route','length'])['interchange'].apply(lambda x: x.tolist()).reset_index().to_dict('record')
Out[240]:
[{'interchange': ['Ealing Broadway', 'Notting Hill Gate', 'Mile End'],
  'length': 103.89,
  'route': 0},
 {'interchange': ['Ealing Broadway'],
  'length': 59.089999999999996,
  'route': 1},
 {'interchange': ['Notting Hill Gate'],
  'length': 40.279999999999994,
  'route': 2},
 {'interchange': ['Mile End'], 'length': 68.86999999999999, 'route': 3}]

我家用笔记本上的600.000行数据帧的时间安排:

设置:

In [245]: a = pd.concat([df] * 10**5)

合并a DF的形状:

In [246]: a.shape
Out[246]: (600000, 3)

timeit:

In [251]: %timeit a.groupby(['route','length'])['interchange'].apply(lambda x: x.tolist()).reset_index()
10 loops, best of 3: 130 ms per loop

非向量化方法(for loops / list comprehension / etc.):

In [262]: %paste
def roganjosh(lst):
    new_list = []
    for key, group in groupby(lst, lambda x: x[0]):
        new_list.append(list(group))

    main_dict = {}
    for item in new_list:
        main_dict[item[0][0]] = {'length': item[0][2], 'interchange': [stn[1] for stn in item]}

    return  main_dict
## -- End pasted text --

In [263]: lst = a.values.tolist()

In [264]: len(lst)
Out[264]: 600000

In [265]: %timeit roganjosh(lst)
1 loop, best of 3: 650 ms per loop