从Python列表创建一个字典数组

5

我想把一个夹杂了数值的列表转换成字典数组。

我正在尝试创建一份Python预测数值列表,以便使用JSON API。一旦我有了字典,我将使用 json.dumps 对其进行处理。

my_list = [35, 2.75, 67, 3.45] # in form of: (value, score, value, score)

理想的结果:

my_array_of_dicts = [{'value':35, 'score':2.75}, {'value':67 'score':3.45}]

这里是我尝试的内容。
第一次尝试:
d = dict(zip(my_list[::2], my_list[1::2]))

同时它还生产...

> {35: 2.75,
   67: 3.45}

我不确定如何获取自定义键,或将每个键值对作为其自己的字典。第二次尝试:
[{'value':i, 'score':i} for i in my_list]]

> [{'value':35, 'score':35}, {'value':2.75, 'score':2.75}, 
   {'value':67, 'score':67}, {'value':3.45, 'score':3.45}] 

离正确还很接近,但是它没有考虑到每个第二个数值都是得分。

8个回答

6

你已经非常接近 zip 版本了。你只需要创建对象并指定键即可。

my_list = [35, 2.75, 67, 3.45] 

[{'value': v, 'score': s} for v, s in zip(my_list[::2], my_list[1::2])]

结果:

[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]

3
在你的第二次尝试中,执行得分:i + 1。在循环中,使用 for i in range(0, len(my_list), 2)。

3
d = map(dict, map(lambda t:zip(('value','score'),t), zip(my_list[::2], my_list[1::2])))
print(list(d))

3

试试这个:

my_list = [35, 2.75, 67, 3.45]
list_of_dicts = [{'value': k, 'score': v} for k, v in zip(iter(my_list), iter(my_list))]
print(list_of_dicts)

输出:

[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]

我的解决方案与使用列表切片的其他人的解决方案之间有一个小的时间比较:
In [1]: my_list = [35, 2.75, 67, 3.45] * 100 # making it longer for better testing results

In [2]: def zip_with_slice():
   ...:     return [{'value': v, 'score': s} for v, s in zip(my_list[::2], my_list[1::2])]
   ...:

In [3]: def zip_with_iter():
   ...:     return [{'value': k, 'score': v} for k, v in zip(iter(my_list), iter(my_list))]
   ...:

In [4]: %timeit zip_with_slice()
56.5 µs ± 1.27 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [5]: %timeit zip_with_iter()
93 µs ± 2.99 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

如您所见,使用迭代器的解决方案比使用切片的解决方案要快得多(5-6倍)。


@aws_apprentice 你的电脑必须更快,因为我的测试显示你的编辑速度为 57.8 µs - iz_
@aws_apprentice 我找到原因了。我正在使用原始列表 * 100 进行测试,以获得更准确的结果,而你正在使用原始列表进行测试。这是有道理的,因为你的解决方案看起来并不像一种改进。 - iz_
@aws_apprentice 你确定你正在使用新的、更长的列表吗?此外,你的 timeit 看起来不太公平,因为你事先进行了实际计算。 - iz_

2

使用列表推导式的一行代码:

[{'value': k, 'score': v} for k, v in [my_list[i: i + 2] for i in range(0, len(my_list), 2)]]

[{'score': 2.75, 'value': 35}, {'score': 3.45, 'value': 67}]

使用您的原始尝试:

[{'value': k, 'score': v} for k,v in zip(my_list[::2], my_list[1::2])]

另一种更详细的方法

from operator import itemgetter

getters = [itemgetter(slice(i, i + 2)) for i in range(0, len(my_list), 2)]
vals = [g(my_list) for g in getters]


def score_vals(s):
    k, v = s
    return {'value': k, 'score': v}

list(map(score_vals, vals))

%timeit list(map(score_vals, vals)) 实际上并没有计时整个计算过程,只计时其中的一小部分。 - iz_

2

使用列表推导式:

>>> my_list = [35, 2.75, 67, 3.45]
>>> my_dict = [{'value': my_list[i], 'score': my_list[i+1]} for i in range(0, len(my_list), 2)]
>>> my_dict
[{'score': 2.75, 'value': 35}, {'score': 3.45, 'value': 67}]

2

另一种使用带参数的字典(**kwargs**)完成此操作的方法:

>>> my_list = [35, 2.75, 67, 3.45]
>>> [dict(value=x,score=y) for x,y in zip(my_list[::2], my_list[1::2])]
[{'value': 35, 'score': 2.75}, {'value': 67, 'score': 3.45}]
>>> 

0
class my_dictionary(dict):

    # __init__ function
    def __init__(self):
        self = dict()

    # Function to add key:value
    def add(self, key, value):
        self[key] = value


# Main Function
dict_obj = my_dictionary()

然后,您可以使用以下代码将保存在tmpkeytmpvalue中的值分配给字典中的键值对。

dict_obj.key = tmpkey
dict_obj.value = tmpvalue
dict_obj.add(dict_obj.key, dict_obj.value)

创建一个字典列表,你只需要创建一个空列表,并将你的字典副本分配给列表中的每个元素。
dicMatrix = []
dictionary_copy = dict_obj.copy()
dicMatrix.append(dictionary_copy)

通过这种方式,您的字典将动态增长。复制字典的原因是,如果每次更改字典的值,新值将添加到列表中,否则字典的引用将被分配给列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接