Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 具有唯一值的置换_Python_Permutation_Itertools - Fatal编程技术网

Python 具有唯一值的置换

Python 具有唯一值的置换,python,permutation,itertools,Python,Permutation,Itertools,itertools.permutations生成的元素根据其位置而不是价值被视为唯一的元素。所以基本上我想避免像这样的重复: >>> list(itertools.permutations([1, 1, 1])) [(1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1)] 之后过滤是不可能的,因为在我的例子中排列的数量太大了 有人知道一个合适的算法吗 多谢各位 编辑: 我基本上想要的是: x = ite

itertools.permutations生成的元素根据其位置而不是价值被视为唯一的元素。所以基本上我想避免像这样的重复:

>>> list(itertools.permutations([1, 1, 1]))
[(1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1)]
之后过滤是不可能的,因为在我的例子中排列的数量太大了

有人知道一个合适的算法吗

多谢各位

编辑:

我基本上想要的是:

x = itertools.product((0, 1, 'x'), repeat=X)
x = sorted(x, key=functools.partial(count_elements, elem='x'))
[''.join(perm) for perm in unique_permutations('abunchofletters')]
from itertools import combinations,chain

l = ["A","B","C","D"]
combs = (combinations(l, r) for r in range(1, len(l) + 1))
list_combinations = list(chain.from_iterable(combs))
这是不可能的,因为
sorted
创建了一个列表,并且itertools.product的输出太大


对不起,我应该已经描述了实际问题。

您可以尝试使用set:

>>> list(itertools.permutations(set([1,1,2,2])))
[(1, 2), (2, 1)]

调用set删除的重复项

您可以尝试使用set:

>>> list(itertools.permutations(set([1,1,2,2])))
[(1, 2), (2, 1)]

调用set removed duplicates

听起来像是在寻找itertools.combines()


听起来您正在寻找itertools.compositions()

编辑(如何工作):

我重写了上面的程序,使其更长,但更具可读性

我通常很难解释某些东西是如何工作的,但让我试试。 为了理解这是如何工作的,您必须了解一个类似但更简单的程序,该程序将产生所有重复排列

def permutations_with_replacement(elements,n):
    return permutations_helper(elements,[0]*n,n-1)#this is generator

def permutations_helper(elements,result_list,d):
    if d<0:
        yield tuple(result_list)
    else:
        for i in elements:
            result_list[d]=i
            all_permutations = permutations_helper(elements,result_list,d-1)#this is generator
            for g in all_permutations:
                yield g
def置换与替换(元素,n):
返回置换_helper(元素,[0]*n,n-1)#这是生成器
def置换辅助程序(元素、结果列表、d):
如果d
编辑(如何工作):

我重写了上面的程序,使其更长,但更具可读性

我通常很难解释某些东西是如何工作的,但让我试试。 为了理解这是如何工作的,您必须了解一个类似但更简单的程序,该程序将产生所有重复排列

def permutations_with_replacement(elements,n):
    return permutations_helper(elements,[0]*n,n-1)#this is generator

def permutations_helper(elements,result_list,d):
    if d<0:
        yield tuple(result_list)
    else:
        for i in elements:
            result_list[d]=i
            all_permutations = permutations_helper(elements,result_list,d-1)#this is generator
            for g in all_permutations:
                yield g
def置换与替换(元素,n):
返回置换_helper(元素,[0]*n,n-1)#这是生成器
def置换辅助程序(元素、结果列表、d):

如果d这取决于实现细节,即排序的iterable的任何排列都是按排序顺序排列的,除非它们是先前排列的重复

from itertools import permutations

def unique_permutations(iterable, r=None):
    previous = tuple()
    for p in permutations(sorted(iterable), r):
        if p > previous:
            previous = p
            yield p

for p in unique_permutations('cabcab', 2):
    print p
给予


这取决于实现细节,即排序的iterable的任何排列都是按排序顺序排列的,除非它们是先前排列的副本

from itertools import permutations

def unique_permutations(iterable, r=None):
    previous = tuple()
    for p in permutations(sorted(iterable), r):
        if p > previous:
            previous = p
            yield p

for p in unique_permutations('cabcab', 2):
    print p
给予

那怎么办

np.unique(itertools.permutations([1, 1, 1]))
问题是排列现在是Numpy数组的行,因此使用了更多内存,但您可以像以前一样循环使用它们

perms = np.unique(itertools.permutations([1, 1, 1]))
for p in perms:
    print p
那怎么办

np.unique(itertools.permutations([1, 1, 1]))
问题是排列现在是Numpy数组的行,因此使用了更多内存,但您可以像以前一样循环使用它们

perms = np.unique(itertools.permutations([1, 1, 1]))
for p in perms:
    print p

前几天我在处理自己的问题时遇到了这个问题。我喜欢Luka Rahne的方法,但我认为在collections library中使用Counter类似乎是一个适度的改进。这是我的密码:

def unique_permutations(elements):
    "Returns a list of lists; each sublist is a unique permutations of elements."
    ctr = collections.Counter(elements)

    # Base case with one element: just return the element
    if len(ctr.keys())==1 and ctr[ctr.keys()[0]] == 1:
        return [[ctr.keys()[0]]]

    perms = []

    # For each counter key, find the unique permutations of the set with
    # one member of that key removed, and append the key to the front of
    # each of those permutations.
    for k in ctr.keys():
        ctr_k = ctr.copy()
        ctr_k[k] -= 1
        if ctr_k[k]==0: 
            ctr_k.pop(k)
        perms_k = [[k] + p for p in unique_permutations(ctr_k)]
        perms.extend(perms_k)

    return perms
这段代码以列表的形式返回每个排列。如果你给它一个字符串,它会给你一个排列列表,其中每个排列都是一个字符列表。如果您希望以字符串列表的形式输出(例如,如果您是一个糟糕的人,您想滥用我的代码来帮助您在拼字游戏中作弊),只需执行以下操作:

x = itertools.product((0, 1, 'x'), repeat=X)
x = sorted(x, key=functools.partial(count_elements, elem='x'))
[''.join(perm) for perm in unique_permutations('abunchofletters')]
from itertools import combinations,chain

l = ["A","B","C","D"]
combs = (combinations(l, r) for r in range(1, len(l) + 1))
list_combinations = list(chain.from_iterable(combs))

前几天我在处理自己的问题时遇到了这个问题。我喜欢Luka Rahne的方法,但我认为在collections library中使用Counter类似乎是一个适度的改进。这是我的密码:

def unique_permutations(elements):
    "Returns a list of lists; each sublist is a unique permutations of elements."
    ctr = collections.Counter(elements)

    # Base case with one element: just return the element
    if len(ctr.keys())==1 and ctr[ctr.keys()[0]] == 1:
        return [[ctr.keys()[0]]]

    perms = []

    # For each counter key, find the unique permutations of the set with
    # one member of that key removed, and append the key to the front of
    # each of those permutations.
    for k in ctr.keys():
        ctr_k = ctr.copy()
        ctr_k[k] -= 1
        if ctr_k[k]==0: 
            ctr_k.pop(k)
        perms_k = [[k] + p for p in unique_permutations(ctr_k)]
        perms.extend(perms_k)

    return perms
这段代码以列表的形式返回每个排列。如果你给它一个字符串,它会给你一个排列列表,其中每个排列都是一个字符列表。如果您希望以字符串列表的形式输出(例如,如果您是一个糟糕的人,您想滥用我的代码来帮助您在拼字游戏中作弊),只需执行以下操作:

x = itertools.product((0, 1, 'x'), repeat=X)
x = sorted(x, key=functools.partial(count_elements, elem='x'))
[''.join(perm) for perm in unique_permutations('abunchofletters')]
from itertools import combinations,chain

l = ["A","B","C","D"]
combs = (combinations(l, r) for r in range(1, len(l) + 1))
list_combinations = list(chain.from_iterable(combs))

大概和卢卡·拉恩的答案一样快,但更简短,更简单

def unique_permutations(elements):
    if len(elements) == 1:
        yield (elements[0],)
    else:
        unique_elements = set(elements)
        for first_element in unique_elements:
            remaining_elements = list(elements)
            remaining_elements.remove(first_element)
            for sub_permutation in unique_permutations(remaining_elements):
                yield (first_element,) + sub_permutation

>>> list(unique_permutations((1,2,3,1)))
[(1, 1, 2, 3), (1, 1, 3, 2), (1, 2, 1, 3), ... , (3, 1, 2, 1), (3, 2, 1, 1)]
它通过设置第一个元素(遍历所有唯一的元素)并遍历所有剩余元素的排列来递归工作

让我们通过(1,2,3,1)的
唯一排列来了解它是如何工作的:

  • 唯一元素是1,2,3
  • 让我们遍历它们:
    第一个元素
    以1开头。
    • 剩余的_元素是[2,3,1](即1,2,3,1减去前1)
    • 我们(递归地)遍历剩余元素的排列:(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1),(3,2,1)
    • 对于每个
      子排列
      ,我们插入
      第一个元素
      :(1,1,2,3),(1,1,3,2)。。。并得出结果
  • 现在我们迭代到
    第一个\u元素
    =2,并执行与上面相同的操作。
    • 剩余的_元素是[1,3,1](即1,2,3,1减去前2)
    • 我们迭代剩余元素的排列:(1,1,3),(1,3,1),(3,1,1)
    • 对于每个
      子排列
      ,我们插入
      第一个元素
      :(2,1,1,3),(2,1,3,1),(2,3,1,1)。。。并得出结果
  • 最后,我们对
    第一个\u元素
    =3执行相同的操作

大概和卢卡·拉恩的答案一样快,但更简短,更简单

def unique_permutations(elements):
    if len(elements) == 1:
        yield (elements[0],)
    else:
        unique_elements = set(elements)
        for first_element in unique_elements:
            remaining_elements = list(elements)
            remaining_elements.remove(first_element)
            for sub_permutation in unique_permutations(remaining_elements):
                yield (first_element,) + sub_permutation

>>> list(unique_permutations((1,2,3,1)))
[(1, 1, 2, 3), (1, 1, 3, 2), (1, 2, 1, 3), ... , (3, 1, 2, 1), (3, 2, 1, 1)]
它通过设置第一个元素(遍历所有唯一的元素)并遍历所有剩余元素的排列来递归工作

让我们通过(1,2,3,1)的
唯一排列来了解它是如何工作的:

  • 唯一元素是1,2,3
  • 让我们遍历它们:
    第一个元素
    以1开头。
    • 剩余的_元素是[2,3,1](即1,2,3,1减去前1)
    • 我们(递归地)遍历剩余元素的排列:(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1),(3,2,1)
    • 对于每个
      子排列
      ,我们插入
      第一个元素
      :(1,1,2,3),
      ['moon', 'mono', 'mnoo', 'omon', 'omno', 'nmoo', 'oomn', 'onmo', 'nomo', 'oonm', 'onom', 'noom']
      
      from itertools import combinations,chain
      
      l = ["A","B","C","D"]
      combs = (combinations(l, r) for r in range(1, len(l) + 1))
      list_combinations = list(chain.from_iterable(combs))
      
      [('A',),
       ('B',),
       ('C',),
       ('D',),
       ('A', 'B'),
       ('A', 'C'),
       ('A', 'D'),
       ('B', 'C'),
       ('B', 'D'),
       ('C', 'D'),
       ('A', 'B', 'C'),
       ('A', 'B', 'D'),
       ('A', 'C', 'D'),
       ('B', 'C', 'D'),
       ('A', 'B', 'C', 'D')]
      
      import statsmodels.formula.api as smf
      import pandas as pd
      
      # create some data
      pd_dataframe = pd.Dataframe(somedata)
      response_column = "Y"
      
      # generate combinations of column/variable names
      l = [col for col in pd_dataframe.columns if col!=response_column]
      combs = (combinations(l, r) for r in range(1, len(l) + 1))
      list_combinations = list(chain.from_iterable(combs))
      
      # generate OLS input string
      formula_base = '{} ~ '.format(response_column)
      list_for_ols = [":".join(list(item)) for item in list_combinations]
      string_for_ols = formula_base + ' + '.join(list_for_ols)
      
      Y ~ A + B + C + D + A:B + A:C + A:D + B:C + B:D + C:D + A:B:C + A:B:D + A:C:D + B:C:D + A:B:C:D'
      
      model = smf.ols(string_for_ols, pd_dataframe).fit()
      model.summary()
      
      import numba
      
      @numba.njit
      def perm_unique_fast(elements): #memory usage too high for large permutations
          eset = set(elements)
          dictunique = dict()
          for i in eset: dictunique[i] = elements.count(i)
          result_list = numba.typed.List()
          u = len(elements)
          for _ in range(u): result_list.append(0)
          s = numba.typed.List()
          results = numba.typed.List()
          d = u
          while True:
              if d > 0:
                  for i in dictunique:
                      if dictunique[i] > 0: s.append((i, d - 1))
              i, d = s.pop()
              if d == -1:
                  dictunique[i] += 1
                  if len(s) == 0: break
                  continue
              result_list[d] = i
              if d == 0: results.append(result_list[:])
              dictunique[i] -= 1
              s.append((i, -1))
          return results
      
      import timeit
      l = [2, 2, 3, 3, 4, 4, 5, 5, 6, 6]
      %timeit list(perm_unique(l))
      #377 ms ± 26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
      
      ltyp = numba.typed.List()
      for x in l: ltyp.append(x)
      %timeit perm_unique_fast(ltyp)
      #293 ms ± 3.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
      
      assert list(sorted(perm_unique(l))) == list(sorted([tuple(x) for x in perm_unique_fast(ltyp)]))
      
      def perm_unique_fast_gen(elements):
          eset = set(elements)
          dictunique = dict()
          for i in eset: dictunique[i] = elements.count(i)
          result_list = list() #numba.typed.List()
          u = len(elements)
          for _ in range(u): result_list.append(0)
          s = list()
          d = u
          while True:
              if d > 0:
                  for i in dictunique:
                      if dictunique[i] > 0: s.append((i, d - 1))
              i, d = s.pop()
              if d == -1:
                  dictunique[i] += 1
                  if len(s) == 0: break
                  continue
              result_list[d] = i
              if d == 0: yield result_list
              dictunique[i] -= 1
              s.append((i, -1))
      
      def perm_helper(head: str, tail: str):
          if len(tail) == 0:
              yield head
          else:
              last_c = None
              for index, c in enumerate(tail):
                  if last_c != c:
                      last_c = c
                      yield from perm_helper(
                          head + c, tail[:index] + tail[index + 1:]
                      )
      
      
      def perm_generator(word):
          yield from perm_helper("", sorted(word))
      
      from itertools import takewhile
      word = "POOL"
      list(takewhile(lambda w: w != word, (x for x in perm_generator(word))))
      # output
      # ['LOOP', 'LOPO', 'LPOO', 'OLOP', 'OLPO', 'OOLP', 'OOPL', 'OPLO', 'OPOL', 'PLOO', 'POLO']
      
      ans=[]
      def fn(a, size): 
          if (size == 1): 
              if a.copy() not in ans:
                  ans.append(a.copy())
                  return
      
          for i in range(size): 
              fn(a,size-1); 
              if size&1: 
                  a[0], a[size-1] = a[size-1],a[0] 
              else: 
                  a[i], a[size-1] = a[size-1],a[i]