简体   繁体   English

通过使用键作为列表索引将python字典转换/映射为列表

[英]convert/map python dictionary to a list, by using the key as the list index

I have a python dictionary as follows: 我有一个python字典,如下所示:

dict = {4:0.65,8:1.23,3:0.43}

I would like to convert this to a python list by using the key as the index to the list. 我想通过使用键作为列表的索引将其转换为python列表。 The desired converted result would be: 所需的转换结果将是:

listLength = 10
plist = [0,0,0,0.43,0.65,0,0,0,1.23,0]

I know how to do the above using a loop but that is not pythonic and it is not fast. 我知道如何使用循环来完成上述操作,但这不是pythonic,而且速度也不快。 What is the most pythonic way to do the above without using a loop. 在不使用循环的情况下执行以上操作的最pythonic方法是什么。

I specially need to do the above with the best performance. 我特别需要以最佳性能执行上述操作。

Since you tag pandas , solution from reindex 由于您标记了pandas ,因此reindex解决方案

pd.Series(d).reindex(range(10),fill_value=0).tolist()
Out[369]: [0.0, 0.0, 0.0, 0.43, 0.65, 0.0, 0.0, 0.0, 1.23, 0.0]

Using numpy and numpy indexing is going to be the most performant solution: 使用numpynumpy索引将是性能最高的解决方案:

out = np.zeros(10)
out[list(d.keys())] = list(d.values())

array([0.  , 0.  , 0.  , 0.43, 0.65, 0.  , 0.  , 0.  , 1.23, 0.  ])

Performance since you asked: 性能既然你问:

k = np.random.randint(1, 100000, 10000)
v = np.random.rand(10000)
d = dict(zip(k, v))

In [119]: %%timeit
     ...: out = np.zeros(100000)
     ...: out[list(d.keys())] = list(d.values())
     ...:
     ...:
1.86 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [120]: %timeit [d.get(i, 0) for i in range(100000)]
17.4 ms ± 231 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [121]: %timeit pd.Series(d).reindex(range(100000),fill_value=0).tolist()
9.77 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

For larger data sets you can gain some speed using np.fromiter directly on the key and value iterators instead of creating lists first. 对于较大的数据集,您可以直接在键和值迭代器上使用np.fromiter而不是先创建列表来提高速度。

Create test case 创建测试用例

>>> d = dict(zip(np.random.randint(1, 10, 1_000_000).cumsum(), np.arange(1_000_000.)))
>>> out = np.zeros(10_000_000)

Define fromiter method 定义fromiter方法

>>> def use_iter():
...     k, v = (np.fromiter(w, dtype=t, count=len(d)) for w, t in [(d.keys(), int), (d.values(), float)])
...     out[k] = v
...     return out

and list method for reference list方法供参考

>>> def use_list():
...     out[list(d.keys())] = list(d.values())
...     return out

and time them 和他们时间

>>> timeit(use_iter, number=100)
4.2583943260106025
>>> timeit(use_list, number=100)
17.10310926999955

Also, check correctness 另外,检查正确性

>>> np.all(use_list() == use_iter())
True

You could to something like this: 您可以这样做:

list_length = 10
d = {4: 0.65, 8: 1.23, 3: 0.43}
plist = [d.get(i, 0) for i in range(list_length)]

print(plist)

Output 输出量

[0, 0, 0, 0.43, 0.65, 0, 0, 0, 1.23, 0]

Note: Don't use the name dict for your own variables, you will shadow the built-in name dict . 注意:请勿将名称dict用作您自己的变量,而是会隐藏内置名称dict

Avoid shadowing the built-in dict . 避免掩盖内置dict Use some other name instead. 请改用其他名称。

dict_ = {4:0.65,8:1.23,3:0.43}
length = max(dict_) + 1  # Get number of entries needed
list_ = [0] * length  # Initialize a list of zeroes
for i in dict_:
    list_[i] = dict_[i]

Using list comprehension 使用列表理解

lst = [d[i] if i in d else 0 for i in range(10)]
print(lst)
# [0, 0, 0, 0.43, 0.65, 0, 0, 0, 1.23, 0]

Expanded: 展开:

lst = []
for i in range(10):
    if i in d:
        lst.append(d[i])
    else:
        lst.append(0)

You can just iterate over the dictionary and place them into a list. 您可以遍历字典并将它们放入列表中。 I am doing error checking to make sure that the key is within the specified list length. 我正在执行错误检查,以确保密钥在指定的列表长度内。

  list = [0] * length
    for key, val in d.items():
        if key < length:
            list[key] = val

If you want the list to be as big as the max key, follow this bellow 如果您希望列表与最大键一样大,请遵循以下提示

maxKey = max(d, key=int)
list = [0] * maxKey
for key, val in d.items():
    list[key] = val

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM