0

我在 python 中使用 itertools生成所有关于一些对称组的向量。

基本上所有只是 x,y,z 轴和符号的排列。我只是不确定确保等效向量不重复的最佳方法是什么

  1. 0 = -0 因此的符号排列[1, 2, 0]应该是[[1, 2, 0], [1, -2, 0], [-1, 2, 0], [-1, -2, 0]]
  2. itertools.permutations( 'AAB' )应该产生[('A', 'B', 'A'), ('B', 'A', 'A'), ('A', 'A', 'B')]即不通过交换等价物来复制每个元素A

我目前的解决方案:

删除dumplicate 我通过一个setlike传递它lst = list(set(lst))。但是我不喜欢创建很多稍后被过滤掉的垃圾。它也任意改变元素的顺序。也可以仅以需要转换的可散列元素(例如元组,但不是列表或 numpy 数组)的形式创建它。

# using itertools.product and set filer
def signPermut( t ):
    lst = []
    n = len(t)
    for signs in itertools.product( [-1,1], repeat=n):
        p = [ ti*si for ti,si in zip(t,signs) ]
        lst.append(tuple(p))
    #return lst
    return list(set(lst))

此函数通过检查零来执行符号置换,但它可能非常低效:

def permutSign( t ):
    lst = [ [] ]
    for c in t:
        lst_ = []
        if c != 0:
            for p in lst:
                lst_.append(p+[ c]) 
                lst_.append(p+[-c])
        else:
            for p in lst:
                lst_.append( p+[c])
        lst = lst_
    return lst

它正在工作,但我在想也许有一些预制的东西......更高效,简单和pythonic

4

3 回答 3

2

也许这更像是 Pythonic:

import itertools

def signProducts(vector):
    svector = [[x,-x] if x != 0 else [x] for x in vector]
    return itertools.product(*svector)

#test:
v = [1,2,0]
for w in signProducts(v): print(w)

输出:

(1, 2, 0)
(1, -2, 0)
(-1, 2, 0)
(-1, -2, 0)
于 2017-01-25T14:43:02.467 回答
1

如何创建一个带有标志的列表并使用itertools.product它:

from itertools import product

lst = [1, 2, 0]

signs = [(1, -1) if item != 0 else (1, ) for item in lst]
print(signs)  # [(1, -1), (1, -1), (1,)]

res = []
for sign in product(*signs):
    res.append([s*n for s, n in zip(sign, lst)])

print(res)  # [[1, 2, 0], [1, -2, 0], [-1, 2, 0], [-1, -2, 0]]

或一口气:

from itertools import product

sgn_lst =  [(n, -n) if n != 0 else (0, ) for n in lst]
print(sgn_lst)  # [(1, -1), (2, -2), (0,)]

res = []
for item in product(*sgn_lst):
    res.append(item)

print(res)  # [(1, 2, 0), (1, -2, 0), (-1, 2, 0), (-1, -2, 0)]

这样,循环内部要做的工作就少了很多。

于 2017-01-25T14:42:48.110 回答
0

我认为无论你在使用 itertools、集合或迭代器方面有多聪明——最重要的是以易于理解的方式编写代码,例如更好地命名 var 并让你很明显地乘以向量:

import itertools
import operator

def genAxes(n):
    return itertools.product((-1, 1), repeat=n)

def multiplyVectors(x, y):
    return itertools.imap(operator.mul, x, y)

def signPermutation(v):
    n = len(v)
    axes = genAxes(n)
    permut = map(lambda a: tuple(multiplyVectors(v, a)), axes)
    return list(set(permut))

v = [0, 1, 2]
print signPermutation(v)

这只是一个示例,如何使其更容易遵循恕我直言。

于 2017-01-25T15:09:17.637 回答