Python中的循环置换运算符

时间:2019-05-16 14:46:49

标签: python python-3.x itertools

我需要一个python函数(可创建函数的函数),该函数可为长度为N的列表创建所有循环置换运算符。

对于python列表a(例如a = [1, 2, 3, 4,5,6], N= 6),可以定义一个函数

def cyclic_perm(a):
    n = len(a)
    b = [[a[i - j] for i in range(n)] for j in range(n)]
    return b

为您提供列表的所有可能的循环排列,在这种情况下为6个列表。

我希望函数不给我列表,而是(在这种情况下)6个运算符,当应用于列表时,每个运算符都会给出排列的列表之一。

4 个答案:

答案 0 :(得分:5)

我不太确定本练习的目标是什么,但是您可以使用部分功能来实现。

from functools import partial

def reorder_from_idx(idx, a):
    return a[idx:] + a[:idx]

def cyclic_perm(a):
    return [partial(reorder_from_idx, i) for i in range(len(a))]


a = [1, 2, 3, 4,5,6]
result = cyclic_perm(a)
print(result)
#[functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 0),
# functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 1),
# functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 2),
# functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 3),
# functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 4),
# functools.partial(<function reorder_from_idx at 0x00000298D92189D8>, 5)]
result[3](a)
#[4, 5, 6, 1, 2, 3]

答案 1 :(得分:3)

您可以编写一个返回函数的函数:

def cyclic_perm(a):
    n = len(a)
    b = [[a[i - j] for i in range(n)] for j in range(n)]
    return b

def cyclic_perm_func(a):
    n = len(a)
    def wrapper(a, n, j):
        def cyc():
            return [a[i - j] for i in range(n)]
        return cyc
    b = [wrapper(a, n, j) for j in range(n)]
    return b

a = [1, 2, 3, 4,5,6]
print(cyclic_perm(a))  # Your original function
f = cyclic_perm_func(a) # f is now a list of functions
print([g() for g in f])  # Let's call each in turn

输出:

[[1, 2, 3, 4, 5, 6], [6, 1, 2, 3, 4, 5], [5, 6, 1, 2, 3, 4], [4, 5, 6, 1, 2, 3], [3, 4, 5, 6, 1, 2], [2, 3, 4, 5, 6, 1]]
[[1, 2, 3, 4, 5, 6], [6, 1, 2, 3, 4, 5], [5, 6, 1, 2, 3, 4], [4, 5, 6, 1, 2, 3], [3, 4, 5, 6, 1, 2], [2, 3, 4, 5, 6, 1]]

请注意wrapper(),这是捕获每个实例中包装函数cyc()所需的所有参数的方式。

答案 2 :(得分:1)

您可以执行以下操作。在input_list上调用cyclic_perm函数将返回操作符(函数)列表,当在input_list上调用该函数时,将为您提供所需的结果。

input_list = [1, 2, 3, 4, 5, 6]


def cyclic_perm(a):
    n = len(a)
    result = []
    for j in range(n):
        def f(l, k=j):
            return list(map(lambda i: l[i - k], range(n)))
        result.append(f)
    return result


for op in cyclic_perm(input_list):
    print(op(input_list))

答案 3 :(得分:0)

鉴于多个循环n,我将您的请求解释为”,实现了一个接受n并返回一个函数的函数,该函数在传递可迭代对象时返回可迭代移位的{{1 }}个职位。”

考虑more_itertools.circular_shifts

给出

n

代码

import functools as ft

import more_itertools as mit


iterable = range(6, 10)

演示

def composed_shifts(n):
    """Return a function of `n` circular shifts."""
    def f(x):    
        return ft.partial(mit.circular_shifts(x).__getitem__, n)()
    return f

详细信息

我们的composed_shifts(1) # 1 # <function __main__.composed_shifts.<locals>.f(x)> composed_shifts(1)(iterable) # 2 # (7, 8, 9, 6) composed_shifts(3)(iterable) # (9, 6, 7, 8) 函数接受composed_shifts()移位的整数,并且

  1. 返回功能
  2. ,当它传递一个可迭代对象时,将从n返回列表索引处的值。在下面查看更多详细信息。

circular shift是一种特定类型的循环置换,如下所示:

mit.circular_shifts()

输出

mit.circular_shifts(iterable))

如图所示,返回所有循环移位的列表。我们只需要一个索引来选择特定的班次[(6, 7, 8, 9), # 0 shifts (7, 8, 9, 6), # 1 " (8, 9, 6, 7), # 2 " (9, 6, 7, 8)] # 3 " 。该选择由n完成,它的一部分是延迟索引将来的列表。

摘要

  • 移位(索引)__getitem__被分为n的{​​{1}}
  • 内部函数__getitem__() composes后一部分函数

通过mit.circular_shifts()安装此第三方库。