给定一个字典,如何将键列表转换为它们的对应值列表,而没有for循环?

时间:2019-07-17 12:44:32

标签: python list numpy dictionary

我的字典:

d = {'a':1, 'b':2, 'c':3}

和我的钥匙清单:

keys = np.array(['a','b','a','c','a','b'])

我希望在不使用for循环的情况下拥有相应值的列表

我尝试通过以下方式使用for循环,但出于我的工作目的,这在计算上过于昂贵。

这是for循环版本。

l = [d[i] for i in keys]

您是否知道一个没有循环的版本,也许利用了np.array的广播..masks?

2 个答案:

答案 0 :(得分:3)

# Approach 1

对于大型阵列,可以使用np.vectorize作为更好的扩展解决方案:

d = {'a':1, 'b':2, 'c':3}
keys = np.array(['a','b','a','c','a','b'])

np.vectorize(d.get)(keys)
# array([1, 2, 1, 3, 1, 2])

# Approach 2

另一种方法是定义一个结构化数组,该数组允许使用混合类型,并使用np.searchsorted

a = np.array(list(d.items()), dtype=[('letter', 'U1'), ('digit', 'i4')])
a['digit'][np.searchsorted(a['letter'], keys)]
# array([1, 2, 1, 3, 1, 2])

让我们检查时间:


d = {'a':1, 'b':2, 'c':3}
keys = np.concatenate([np.array(['a','b','a','c','a','b'])]*1000)

def str_array(d, keys):
    items = list(d.items())
    # more general solution checking appropiate dtype
    dtype_int = np.max(list(zip(*items))[1]).itemsize
    # setting corresponding dtype using f-strings
    a = np.array(items, dtype=[('letter', 'U1'), ('digit', f'i{dtype_int}')])
    return a['digit'][np.searchsorted(a['letter'], keys)]

%timeit [d[i] for i in keys]
# 1.86 ms ± 99.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.vectorize(d.get)(keys)
# 808 µs ± 18.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit str_array(d, keys)
# 75.7 µs ± 5.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

如您所见,与简单的列表理解相比,使用np.searchsorted的第二种方法可以提高 20x 的速度。

答案 1 :(得分:0)

我不了解相对性能,但是我发现此解决方案非常快速且简单。 将您的密钥转换为系列,然后使用内置的map函数返回您的答案。

import pandas as pd
d = {'a':1, 'b':2, 'c':3}
keys = np.array(['a','b','a','c','a','b'])
keys1 = pd.Series(keys)
keys1.map(d)