有没有很好的pythonic方式来进行左值排列?

时间:2019-12-05 16:24:23

标签: python list-comprehension permutation lvalue

假设您要对数据数组进行不对称转换,但是您希望数据关于此转换是对称的。你会

  1. 对数据进行随机排列,
  2. 进行不对称转换排列的数据,
  3. 反向排列以将数据放回原位。

问题:在原始数据空间上进行排列以将数据放回原处比建立反向排列要容易得多。


示例:要生成与背景色相距甚远的随机前景色,您需要远离三种基色之一,而其他两种颜色都可能是随机的。 假设我的背景色是:

import random
background = tuple(random.randint(0, 0xff) for _ in range(3))

让我们随机选择一个组件:

selector = random.choice(((0, 1, 2), (1, 0, 2), (2, 0 ,1)))

然后,我将选择第一个组件,而不是那个组件:

far_component = 0xff if background[selector[0]] < 0x80 else 0

然后根据我的初始选择创建前景颜色:

foreground = list(range(3))
foreground[selector[0]] = far_component
foreground[selector[1]] = random.randint(0, 0xff)
foreground[selector[2]] = random.randint(0, 0xff)

在这种简单的情况下,事情是很容易管理的,但让我们想象一个更复杂的情况,它具有更多维度。它将需要一个循环来管理所有输出分配,如下所示:

variable = len(selector)*None # If ever variable doesn't exist yet.
for i in range(len(selector)):
    variable[selector[i]] = ordered_source_tuple[i]

是否会有一种很好的pythonic方式编写这样的赋值,该赋值看起来像是变量的理解列表。像这样的东西(由于左侧部分不是LValues的元组,因此显然不起作用):

(variable[i] for i in selector) = ordered_source_tuple

找到反向排列来写这不是简单的操作

variable = ordered_source_tuple(reversed_selector)

3 个答案:

答案 0 :(得分:0)

创建新颜色,然后在分配给foreground之前对其进行填充。

import random
from operator import itemgetter


background = tuple(random.randint(0, 0xff) for _ in range(3))
selector = random.choice(((0, 1, 2), (1, 0, 2), (2, 0 ,1)))
far_component = 0xff if background[selector[0]] < 0x80 else 0

permute = itemgetter(*selector)
components = [far_component, random.randint(), 0xff), random.randint(0, 0xff)]
foreground = permute(components)

答案 1 :(得分:0)

这可能是作弊,但是字典呢?

variable = dict(zip(selector, ordered_source_tuple))

如果要将其转换为按键排序的对象,则可以

variable_list = [variable[i] for i in range(len(selector))]

答案 2 :(得分:0)

这不再是单线的,但是如果您像this answer中那样定义一个辅助函数,它将变成一个:

def inverted_permutation(p):
    inverse = [0] * len(p)
    for i, p in enumerate(p):
        inverse[p] = i
    return inverse

variable = tuple(source[i] for i in inverted_permutation(selector))

当然,这或多或少地等同于您的赋值循环,但将其隐藏在某种通用函数中。