## 2014-11-29

### Enumerate 2-Permutations of List Elements

リスト要素の2-順列を列挙する

This is a question on how to enumerate every 2-permutation of elements in a list.
この問題は、リスト要素の全ての2-順列を列挙する方法に関するものです。
Community Answers > permute a list, output to csv

Source = [11, 22, 33]
2-Permutations = [[11, 22], [11, 33], [22, 11], [22, 33], [33, 11], [33, 22]]

I suggested these 3 ways.

1. ListExploder+AttributeRenamer+FeatureMerger+ListExploder+Tester
2. ListExploder+InlineQuerier (SQL statement)
3. PythonCaller (Python script)

ここではもうひとつ追加します。
4. TclCaller (Tcl script)+ListExploder

-----
# TclCaller Script Example
proc extractPermutation {} {
set values {}
set range {}
for {set i 0} {[FME_AttributeExists "List{\$i}"]} {incr i} {
lappend values [FME_GetAttribute "List{\$i}"]
lappend range \$i
}
set index 0
foreach i \$range v1 \$values {
foreach j \$range v2 \$values {
if {\$i != \$j} {
FME_SetAttribute "_join{\$index}.Field1" \$v1
FME_SetAttribute "_join{\$index}.Field2" \$v2
incr index
}
}
}
}
-----

My favorite is the SQL approach, and Tcl is also difficult to throw away. But Python could be the most efficient solution in this case.
SQLアプローチが気に入っているしTclも捨てがたいのですが、この場合はPythonが最も効率的かも知れません。
-----
# PythonCaller Script Example
import fmeobjects
class FeatureProcessor(object):
def input(self, feature):
L = feature.getAttribute('List{}')
if L:
for v1, v2 in [(v1, v2) for i, v1 in enumerate(L) for j, v2 in enumerate(L) if i != j]:
newFeature = fmeobjects.FMEFeature()
# If you need to retain the List{} and other attributes,
# replace the line above with this.
# newFeature = feature.cloneAttributes()
newFeature.setAttribute('Field1', v1)
newFeature.setAttribute('Field2', v2)
self.pyoutput(newFeature)
-----

FME 2014 SP4 build 14433

=====
2014-12-01: Probably this script works a treat for enumerating general K-Permutations (K is an arbitrary number).
おそらくこのスクリプトは、一般のK-順列をうまく列挙します（Kは任意の数）。
-----
# PythonCaller Script Example
# Enumerates K-Permutations of List Elements.
# Results will be stored by a nested list named "_perm{}.item{}".
# Assume that "K" (number of items in a permutation) will be specified
# by a feature attribute called "_k".
class PermutationEnumerator(object):
def input(self, feature):
src = feature.getAttribute('_list{}')
self.k = int(feature.getAttribute('_k'))
if self.k <= len(src):
self.i = 0
for i in range(len(src)):
s = src[:]
t = [s.pop(i)]
self.enumeratePermutation(feature, s, t, 1)
else:
feature.setAttribute('_rejected', 1)
self.pyoutput(feature)

def enumeratePermutation(self, feature, s, t, depth):
if self.k <= depth:
for j in range(self.k):
feature.setAttribute('_perm{%d}.item{%d}' % (self.i, j), t[j])
self.i += 1
else:
for i in range(len(s)):
c, d, = s[:], t[:]
d.append(c.pop(i))
self.enumeratePermutation(feature, c, d, depth + 1)
-----
=====
FME Store の ListSubsetEnumerator トランスフォーマーも参照してください。