我在python中使用itertools生成所有vectors respecting some symmetry groups。
基本上所有只是x,y,z轴和符号的排列。我不确定什么是确保等效载体不重复的最佳方法。
[1, 2, 0]
的签名应该只是[[1, 2, 0], [1, -2, 0], [-1, 2, 0], [-1, -2, 0]]
itertools.permutations( 'AAB' )
应该生成[('A', 'B', 'A'), ('B', 'A', 'A'), ('A', 'A', 'B')]
,即不通过交换等价A
我目前的解决方案:
删除dumplicate我将其传递给像set
这样的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
答案 0 :(得分: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)
答案 1 :(得分: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)]
这样,循环内部的工作量就会减少很多。
答案 2 :(得分:0)
我认为无论你使用itertools,集合还是迭代器有多聪明,最重要的是以易于理解的方式编写代码,例如:为了更好地命名变量并且明显地增加向量,它不会受到伤害:
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)
这只是一个如何让我们更容易关注恕我直言的例子。