根据给定索引交换两个列表的值

时间:2018-07-02 11:06:25

标签: python arrays list numpy indexing

我有一个列表,该列表由两个numpy数组组成,第一个数组告诉值的索引,第二个数组包含所属值本身。看起来像这样:

x_glob = [[0, 2], [85, 30]]

一个函数现在正在接收以下输入:

x = [-10, 0, 77, 54]

我的目标是根据x_glob中给定的索引数组,将x的值与x_glob中的值交换。此示例应导致如下所示:

x_new = [85, 0, 30, 54]

我确实有使用循环的解决方案。但是我很确定python中有一种方法可以更有效,更优雅地解决此问题。

谢谢!

3 个答案:

答案 0 :(得分:3)

NumPy arrays may be indexed with other arrays,这使得替换工作变得轻而易举。

您需要做的就是用x_glob[0]索引第二个数组,然后分配x_glob[1]

x[x_glob[0]] = x_glob[1]

要查看的工作原理,只需查看索引结果即可:

>>> x[x_glob[0]]
array([-10,  77])

结果是一个包含我们需要替换的两个值的数组,然后将其替换为另一个numpy数组x_glob[1],以实现所需的结果。


>>> x_glob = np.array([[0, 2], [85, 30]])
>>> x = np.array([-10, 0, 77, 54])
>>> x[x_glob[0]] = x_glob[1]
>>> x
array([85,  0, 30, 54])

答案 1 :(得分:2)

对于非numpy的解决方案,您可以创建一个dict将索引从x_glob映射到各自的值,然后对该字典的get使用列表推导方法:

>>> x_glob = [[0, 2], [85, 30]]
>>> x = [-10, 0, 77, 54]
>>> d = dict(zip(*x_glob))
>>> [d.get(i, n) for i, n in enumerate(x)]
[85, 0, 30, 54]

或者将map与多个参数列表一起使用(或不使用itertools.starmapzip一起使用)

>>> list(map(d.get, *zip(*enumerate(x))))
[85, 0, 30, 54]

答案 2 :(得分:2)

我的解决方案还使用for循环,但是它很短且优雅(我认为),可以就位并且有效,因为它不必遍历完整的x数组,而只需遍历glob列表即可:< / p>

for k,v in zip(*x_glob):
    x[k] = v