सूची के सभी क्रमपरिवर्तन कैसे उत्पन्न करें?


592

आप उस सूची में तत्वों के प्रकार से स्वतंत्र रूप से पायथन में एक सूची के सभी क्रमपरिवर्तन कैसे उत्पन्न करते हैं?

उदाहरण के लिए:

permutations([])
[]

permutations([1])
[1]

permutations([1, 2])
[1, 2]
[2, 1]

permutations([1, 2, 3])
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]

5
मैं पुनरावर्ती, स्वीकृत उत्तर - टुडे से सहमत हूं। हालाँकि, यह अभी भी एक बड़ी कंप्यूटर विज्ञान समस्या के रूप में वहाँ लटका हुआ है। स्वीकृत उत्तर घातीय जटिलता (2 ^ NN = len (सूची)) के साथ इस समस्या को हल करता है (
बहुविकल्पी

37
@FlipMcF बहुपद समय में इसे "हल" करना मुश्किल होगा, यह देखते हुए कि यह फैक्टरियल समय भी सिर्फ उत्पादन को बढ़ाता है ... तो, नहीं, यह संभव नहीं है।
थॉमस

जवाबों:


488

अजगर 2.6 के साथ शुरू (और यदि आप अजगर 3 पर हैं) यदि आप एक है मानक पुस्तकालय इस के लिए उपकरण: itertools.permutations

import itertools
list(itertools.permutations([1, 2, 3]))

यदि आप किसी कारण से एक पुराने अजगर (<2.6) का उपयोग कर रहे हैं या बस यह जानने के लिए उत्सुक हैं कि यह कैसे काम करता है, तो यहां एक अच्छा तरीका, http://code.activestate.com/recipes/252178/ से लिया गया है :

def all_perms(elements):
    if len(elements) <=1:
        yield elements
    else:
        for perm in all_perms(elements[1:]):
            for i in range(len(elements)):
                # nb elements[0:1] works in both string and list contexts
                yield perm[:i] + elements[0:1] + perm[i:]

वैकल्पिक दृष्टिकोण के एक जोड़े के प्रलेखन में सूचीबद्ध हैं itertools.permutations। यहां एक है:

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = range(n)
    cycles = range(n, n-r, -1)
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

और एक और, के आधार पर itertools.product:

def permutations(iterable, r=None):
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    for indices in product(range(n), repeat=r):
        if len(set(indices)) == r:
            yield tuple(pool[i] for i in indices)

14
यह और अन्य पुनरावर्ती समाधानों में सभी रैम खाने की एक संभावित खतरा है यदि
अनुमत

3
वे बड़ी सूचियों के साथ पुनरावृत्ति सीमा (और मरो) तक भी पहुंचते हैं
dbr

58
bgbg, dbr: इसका उपयोग एक जनरेटर के रूप में होता है, इसलिए फ़ंक्शन स्वयं मेमोरी को नहीं खाएगा। इसके लिए आप पर छोड़ दिया कि कैसे itter का उपभोग करने के लिए all_perms द्वारा लौटे (कहते हैं कि आप डिस्क पर प्रत्येक पुनरावृत्ति लिख सकते हैं और स्मृति के लिए चिंता नहीं कर सकते हैं)। मुझे पता है कि यह पोस्ट पुरानी है लेकिन मैं इसे उन सभी के लाभ के लिए लिख रहा हूं जो इसे पढ़ते हैं। इसके अलावा अब, सबसे अच्छा तरीका यह होगा कि कई लोगों द्वारा बताए गए itertools.permutations () का उपयोग करें।
जगदीश चड्ढा

18
सिर्फ एक जनरेटर नहीं है। यदि यह स्पष्ट नहीं है, तो यह नेस्टेड जनरेटर का उपयोग कर रहा है, जो पिछले एक को कॉल स्टैक तक देता है। यह O (n) मेमोरी का उपयोग करता है, जो अच्छा है।
cdunn2001

1
पुनश्च: मैं for i in range(len(elements))इसके बजाय , के साथ तय की for i in range(len(elements)+1)। वास्तव में, एकल-आउट तत्व अलग-अलग स्थिति elements[0:1]में हो सकता है len(elements), परिणाम में, नहीं len(elements)+1
एरिक ओ लेबिगॉट

339

और अजगर 2.6 पर :

import itertools
itertools.permutations([1,2,3])

(एक जनरेटर के रूप में लौटा। list(permutations(l))सूची के रूप में वापस जाने के लिए उपयोग करें ।)


15
पाइथन 3 में भी काम करता है
घर

10
ध्यान दें कि एक rपैरामीटर मौजूद है , उदाहरण के लिए itertools.permutations([1,2,3], r=2), जो 2 तत्वों का चयन करते हुए सभी संभावित क्रमपरिवर्तन उत्पन्न करेगा:[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
toto_tico

277

पायथन 2.6 और इसके बाद के संस्करण के साथ निम्नलिखित कोड

सबसे पहले, आयात itertools:

import itertools

क्रमपरिवर्तन (आदेश मायने रखता है):

print list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
(2, 1), (2, 3), (2, 4),
(3, 1), (3, 2), (3, 4),
(4, 1), (4, 2), (4, 3)]

संयोजन (आदेश कोई फर्क नहीं पड़ता):

print list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]

कार्टेशियन उत्पाद (कई पुनरावृत्तियों के साथ):

print list(itertools.product([1,2,3], [4,5,6]))
[(1, 4), (1, 5), (1, 6),
(2, 4), (2, 5), (2, 6),
(3, 4), (3, 5), (3, 6)]

कार्टेशियन उत्पाद (एक चलने योग्य और स्वयं के साथ):

print list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]


`प्रिंट सूची (itertools.permutations ([1,2,3,4], 2)) ^` सिंटैक्सऑयोर: अमान्य सिंटैक्स` बस वीएस कोड का उपयोग करके शुरू करना मैंने क्या गलत किया? सूचक "सूची" के "टी" के तहत इंगित कर रहा है
गस

39
def permutations(head, tail=''):
    if len(head) == 0: print tail
    else:
        for i in range(len(head)):
            permutations(head[0:i] + head[i+1:], tail+head[i])

कहा जाता है:

permutations('abc')

क्यों प्रिंट पूंछ और फिर कोई नहीं लौटा? बदले में पूंछ क्यों नहीं? वैसे भी कुछ भी क्यों नहीं लौटाया?
Bugmenot123

30
#!/usr/bin/env python

def perm(a, k=0):
   if k == len(a):
      print a
   else:
      for i in xrange(k, len(a)):
         a[k], a[i] = a[i] ,a[k]
         perm(a, k+1)
         a[k], a[i] = a[i], a[k]

perm([1,2,3])

आउटपुट:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]

जैसा कि मैं सूची की सामग्री को स्वैप कर रहा हूं, इसके लिए इनपुट के रूप में एक परिवर्तनशील अनुक्रम प्रकार की आवश्यकता है। जैसे perm(list("ball"))काम करेंगे और perm("ball")नहीं करेंगे क्योंकि आप एक स्ट्रिंग नहीं बदल सकते।

यह पायथन कार्यान्वयन हॉरोविट्ज़, साहनी और राजसेकरन द्वारा कंप्यूटर एल्गोरिदम में प्रस्तुत एल्गोरिदम से प्रेरित है ।


मुझे लगता है कि कश्मीर की लंबाई या क्रमपरिवर्तन है। K = 2 आउटपुट के लिए [1, 2, 3]। क्या यह (१, २) (१, ३) (२, १) (२, ३) (३, १) (३, २) नहीं होना चाहिए ??
कॉन्सटैनटिनो मोनाकोपुलोस

k उस तत्व का सूचकांक है जिसे आप स्वैप करना चाहते हैं
sf8193

22

यह समाधान एक जनरेटर को लागू करता है, स्मृति पर सभी क्रमपरिवर्तन से बचने के लिए:

def permutations (orig_list):
    if not isinstance(orig_list, list):
        orig_list = list(orig_list)

    yield orig_list

    if len(orig_list) == 1:
        return

    for n in sorted(orig_list):
        new_list = orig_list[:]
        pos = new_list.index(n)
        del(new_list[pos])
        new_list.insert(0, n)
        for resto in permutations(new_list[1:]):
            if new_list[:1] + resto <> orig_list:
                yield new_list[:1] + resto

16

एक कार्यात्मक शैली में

def addperm(x,l):
    return [ l[0:i] + [x] + l[i:]  for i in range(len(l)+1) ]

def perm(l):
    if len(l) == 0:
        return [[]]
    return [x for y in perm(l[1:]) for x in addperm(l[0],y) ]

print perm([ i for i in range(3)])

परिणाम:

[[0, 1, 2], [1, 0, 2], [1, 2, 0], [0, 2, 1], [2, 0, 1], [2, 1, 0]]

15

निम्नलिखित कोड जनरेटर के रूप में कार्यान्वित की गई किसी सूची की एक इन-प्लेस अनुमति है। चूंकि यह केवल सूची का संदर्भ देता है, सूची को जनरेटर के बाहर संशोधित नहीं किया जाना चाहिए। समाधान गैर-पुनरावर्ती है, इसलिए कम मेमोरी का उपयोग करता है। इनपुट सूची में तत्वों की कई प्रतियों के साथ भी अच्छी तरह से काम करें।

def permute_in_place(a):
    a.sort()
    yield list(a)

    if len(a) <= 1:
        return

    first = 0
    last = len(a)
    while 1:
        i = last - 1

        while 1:
            i = i - 1
            if a[i] < a[i+1]:
                j = last - 1
                while not (a[i] < a[j]):
                    j = j - 1
                a[i], a[j] = a[j], a[i] # swap the values
                r = a[i+1:last]
                r.reverse()
                a[i+1:last] = r
                yield list(a)
                break
            if i == first:
                a.reverse()
                return

if __name__ == '__main__':
    for n in range(5):
        for a in permute_in_place(range(1, n+1)):
            print a
        print

    for a in permute_in_place([0, 0, 1, 1, 1]):
        print a
    print

15

मेरी राय में एक बहुत स्पष्ट तरीका यह भी हो सकता है:

def permutList(l):
    if not l:
            return [[]]
    res = []
    for e in l:
            temp = l[:]
            temp.remove(e)
            res.extend([[e] + r for r in permutList(temp)])

    return res

11
list2Perm = [1, 2.0, 'three']
listPerm = [[a, b, c]
            for a in list2Perm
            for b in list2Perm
            for c in list2Perm
            if ( a != b and b != c and a != c )
            ]
print listPerm

आउटपुट:

[
    [1, 2.0, 'three'], 
    [1, 'three', 2.0], 
    [2.0, 1, 'three'], 
    [2.0, 'three', 1], 
    ['three', 1, 2.0], 
    ['three', 2.0, 1]
]

2
हालांकि यह तकनीकी रूप से वांछित उत्पादन करता है, आप कुछ हल कर रहे हैं जो O (n ^ n) में O (n lg n) हो सकता है - बड़े सेट के लिए "थोड़ा" अक्षम।
जेम्स

3
@ नाम: मैं आपके द्वारा दिए गए O (n log n) से थोड़ा भ्रमित हूं: क्रमपरिवर्तन की संख्या n है!, जो पहले से O (n log n) से बहुत बड़ी है; इसलिए, मैं यह नहीं देख सकता कि कोई समाधान O (n लॉग एन) कैसे हो सकता है। हालाँकि, यह सच है कि यह समाधान O (n ^ n) में है, जो n की तुलना में बहुत बड़ा है! जैसा कि स्टर्लिंग के सन्निकटन से स्पष्ट है।
एरिक ओ लेबिगॉट

9

मैंने भाज्य संख्या प्रणाली के आधार पर एक एल्गोरिथ्म का उपयोग किया - लंबाई n की सूची के लिए, आप प्रत्येक क्रमांकन आइटम को आइटम द्वारा इकट्ठा कर सकते हैं, प्रत्येक चरण में छोड़ी गई वस्तुओं से चयन कर सकते हैं। आपके पास पहले आइटम के लिए n विकल्प हैं, दूसरे के लिए n-1, और अंतिम के लिए केवल एक है, इसलिए आप किसी संख्या के अंकों को भाज्य संख्या प्रणाली में सूचकांकों के रूप में उपयोग कर सकते हैं। इस तरह से संख्या 0 के माध्यम से -1 -1 लेक्सिकोग्राफिक क्रम में सभी संभावित क्रमपरिवर्तन के अनुरूप है।

from math import factorial
def permutations(l):
    permutations=[]
    length=len(l)
    for x in xrange(factorial(length)):
        available=list(l)
        newPermutation=[]
        for radix in xrange(length, 0, -1):
            placeValue=factorial(radix-1)
            index=x/placeValue
            newPermutation.append(available.pop(index))
            x-=index*placeValue
        permutations.append(newPermutation)
    return permutations

permutations(range(3))

उत्पादन:

[[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]

यह विधि गैर-पुनरावर्ती है, लेकिन यह मेरे कंप्यूटर पर थोड़ा धीमा है और xrange एक त्रुटि उठाता है जब n! एक C लंबे पूर्णांक (n = 13 मेरे लिए) में परिवर्तित होने के लिए बहुत बड़ा है। यह पर्याप्त था जब मुझे इसकी आवश्यकता थी, लेकिन एक लंबे शॉट के द्वारा कोई इटर्टूलसस्पर्मेशन नहीं है।


3
नमस्ते, ढेर अतिप्रवाह में आपका स्वागत है। हालांकि ब्रूट फोर्स मेथड को पोस्ट करने की अपनी खूबियां हैं, अगर आपको नहीं लगता कि आपका समाधान स्वीकार किए गए समाधान से बेहतर है, तो शायद आपको इसे पोस्ट नहीं करना चाहिए (विशेषकर एक पुराने प्रश्न पर जो पहले से ही बहुत सारे उत्तर हैं)।
हननेले

1
मैं वास्तव में एक क्रूर-बल गैर-पुस्तकालय दृष्टिकोण की तलाश में था, इसलिए धन्यवाद!
जे टेलर

8

ध्यान दें कि इस एल्गोरिथ्म में एक n factorialसमय जटिलता है, जहां nइनपुट सूची की लंबाई है

रन पर परिणाम प्रिंट करें:

global result
result = [] 

def permutation(li):
if li == [] or li == None:
    return

if len(li) == 1:
    result.append(li[0])
    print result
    result.pop()
    return

for i in range(0,len(li)):
    result.append(li[i])
    permutation(li[:i] + li[i+1:])
    result.pop()    

उदाहरण:

permutation([1,2,3])

आउटपुट:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]

8

वास्तव में प्रत्येक क्रमपरिवर्तन के पहले तत्व से अधिक पुनरावृति हो सकती है, जैसा कि tzwenn के उत्तर में है। हालाँकि इस समाधान को इस प्रकार लिखना अधिक कुशल है:

def all_perms(elements):
    if len(elements) <= 1:
        yield elements  # Only permutation possible = no permutation
    else:
        # Iteration over the first element in the result permutation:
        for (index, first_elmt) in enumerate(elements):
            other_elmts = elements[:index]+elements[index+1:]
            for permutation in all_perms(other_elmts): 
                yield [first_elmt] + permutation

यह समाधान लगभग 30% तेज है, जाहिरा तौर पर len(elements) <= 1इसके बजाय समाप्त होने वाली पुनरावृत्ति के लिए धन्यवाद 0। यह बहुत अधिक मेमोरी-कुशल है, क्योंकि यह एक जनरेटर फ़ंक्शन (थ्रू yield) का उपयोग करता है , जैसे कि रिकार्डो रेयेस के समाधान में।


6

यह सूची समझ का उपयोग करते हुए हास्केल कार्यान्वयन से प्रेरित है:

def permutation(list):
    if len(list) == 0:
        return [[]]
    else:
        return [[x] + ys for x in list for ys in permutation(delete(list, x))]

def delete(list, item):
    lc = list[:]
    lc.remove(item)
    return lc

6

नियमित कार्यान्वयन (कोई उपज नहीं - स्मृति में सब कुछ करेगा):

def getPermutations(array):
    if len(array) == 1:
        return [array]
    permutations = []
    for i in range(len(array)): 
        # get all perm's of subarray w/o current item
        perms = getPermutations(array[:i] + array[i+1:])  
        for p in perms:
            permutations.append([array[i], *p])
    return permutations

यील्ड कार्यान्वयन:

def getPermutations(array):
    if len(array) == 1:
        yield array
    else:
        for i in range(len(array)):
            perms = getPermutations(array[:i] + array[i+1:])
            for p in perms:
                yield [array[i], *p]

मूल विचार 1 स्थिति के लिए सरणी में सभी तत्वों पर जाने के लिए है, और फिर 2 की स्थिति में 1 के लिए चुने गए तत्व के बिना बाकी सभी तत्वों पर जाएं, आदि आप पुनरावृत्ति के साथ ऐसा कर सकते हैं , जहां स्टॉप मानदंड 1 तत्व की एक सरणी के लिए हो रहा है - जिस स्थिति में आप उस सरणी को वापस करते हैं।

यहाँ छवि विवरण दर्ज करें


यह मेरे लिए काम नहीं करता है _> ValueError: ऑपरेंड्स को इस रेखा के लिए आकृतियों (0,) (2,) के साथ एक साथ प्रसारित नहीं किया जा सकता है :perms = getPermutations(array[:i] + array[i+1:])
RK1

@ RK1 इनपुट क्या था?
डेविड रेफेली

मैं एक numpyसरणी में गुजर रहा हूँ _> getPermutations(np.array([1, 2, 3])), मैं देख रहा हूँ यह एक सूची के लिए काम करता है, बस के रूप में उलझन में आ गया है arg है array:)
RK1

@ RK1 को खुशी है कि यह काम करता है :-) सूची अजगर में एक कीवर्ड है, इसलिए यह आमतौर पर आपके पैरामीटर को एक कीवर्ड कहने के लिए एक अच्छा विचार नहीं है, क्योंकि यह "छाया" करेगा। इसलिए मैं शब्द सरणी का उपयोग करता हूं, क्योंकि यह उस सूची की वास्तविक कार्यक्षमता है जिसका मैं उपयोग कर रहा हूं - उनके सरणी की तरह। मुझे लगता है कि अगर मैं दस्तावेज लिखूंगा तो मैं इसे स्पष्ट करूंगा। इसके अलावा, मेरा मानना ​​है कि बुनियादी "साक्षात्कार" प्रश्नों को बाहरी पैकेजों के बिना हल करना चाहिए, जैसे कि खसखस।
डेविड रेफेली

हाहा यह सच है, हाँ इसके साथ उपयोग करने की कोशिश कर रहा था numbaऔर गति के साथ लालची हो गया था इसलिए इसे विशेष रूप से numpyसरणियों के साथ उपयोग करने की कोशिश की
RK1

4

प्रदर्शन के लिए, नुथ से प्रेरित एक खस्ता समाधान , (p22):

from numpy import empty, uint8
from math import factorial

def perms(n):
    f = 1
    p = empty((2*n-1, factorial(n)), uint8)
    for i in range(n):
        p[i, :f] = i
        p[i+1:2*i+1, :f] = p[:i, :f]  # constitution de blocs
        for j in range(i):
            p[:i+1, f*(j+1):f*(j+2)] = p[j+1:j+i+2, :f]  # copie de blocs
        f = f*(i+1)
    return p[:n, :]

मेमोरी के बड़े ब्लाकों की नकल करने से समय की बचत होती है - यह 20x से भी तेज है list(itertools.permutations(range(n)):

In [1]: %timeit -n10 list(permutations(range(10)))
10 loops, best of 3: 815 ms per loop

In [2]: %timeit -n100 perms(10) 
100 loops, best of 3: 40 ms per loop

3
from __future__ import print_function

def perm(n):
    p = []
    for i in range(0,n+1):
        p.append(i)
    while True:
        for i in range(1,n+1):
            print(p[i], end=' ')
        print("")
        i = n - 1
        found = 0
        while (not found and i>0):
            if p[i]<p[i+1]:
                found = 1
            else:
                i = i - 1
        k = n
        while p[i]>p[k]:
            k = k - 1
        aux = p[i]
        p[i] = p[k]
        p[k] = aux
        for j in range(1,(n-i)/2+1):
            aux = p[i+j]
            p[i+j] = p[n-j+1]
            p[n-j+1] = aux
        if not found:
            break

perm(5)

3

यहाँ एक एल्गोरिथ्म है जो कि बर्स के समाधान के समान नई इंटरमीडिएट सूचियों को बनाने के बिना https://stackoverflow.com/a/108651/184528 पर काम करता है ।

def permute(xs, low=0):
    if low + 1 >= len(xs):
        yield xs
    else:
        for p in permute(xs, low + 1):
            yield p        
        for i in range(low + 1, len(xs)):        
            xs[low], xs[i] = xs[i], xs[low]
            for p in permute(xs, low + 1):
                yield p        
            xs[low], xs[i] = xs[i], xs[low]

for p in permute([1, 2, 3, 4]):
    print p

आप यहां अपने लिए कोड आज़मा सकते हैं: http://repl.it/J9v


3

पुनरावृत्ति की सुंदरता:

>>> import copy
>>> def perm(prefix,rest):
...      for e in rest:
...              new_rest=copy.copy(rest)
...              new_prefix=copy.copy(prefix)
...              new_prefix.append(e)
...              new_rest.remove(e)
...              if len(new_rest) == 0:
...                      print new_prefix + new_rest
...                      continue
...              perm(new_prefix,new_rest)
... 
>>> perm([],['a','b','c','d'])
['a', 'b', 'c', 'd']
['a', 'b', 'd', 'c']
['a', 'c', 'b', 'd']
['a', 'c', 'd', 'b']
['a', 'd', 'b', 'c']
['a', 'd', 'c', 'b']
['b', 'a', 'c', 'd']
['b', 'a', 'd', 'c']
['b', 'c', 'a', 'd']
['b', 'c', 'd', 'a']
['b', 'd', 'a', 'c']
['b', 'd', 'c', 'a']
['c', 'a', 'b', 'd']
['c', 'a', 'd', 'b']
['c', 'b', 'a', 'd']
['c', 'b', 'd', 'a']
['c', 'd', 'a', 'b']
['c', 'd', 'b', 'a']
['d', 'a', 'b', 'c']
['d', 'a', 'c', 'b']
['d', 'b', 'a', 'c']
['d', 'b', 'c', 'a']
['d', 'c', 'a', 'b']
['d', 'c', 'b', 'a']

3

यह एल्गोरिथ्म सबसे प्रभावी है, यह पुनरावर्ती कॉल में सरणी पासिंग और हेरफेर से बचा जाता है, पायथन 2, 3 में काम करता है:

def permute(items):
    length = len(items)
    def inner(ix=[]):
        do_yield = len(ix) == length - 1
        for i in range(0, length):
            if i in ix: #avoid duplicates
                continue
            if do_yield:
                yield tuple([items[y] for y in ix + [i]])
            else:
                for p in inner(ix + [i]):
                    yield p
    return inner()

उपयोग:

for p in permute((1,2,3)):
    print(p)

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

3
def pzip(c, seq):
    result = []
    for item in seq:
        for i in range(len(item)+1):
            result.append(item[i:]+c+item[:i])
    return result


def perm(line):
    seq = [c for c in line]
    if len(seq) <=1 :
        return seq
    else:
        return pzip(seq[0], perm(seq[1:]))

3

अन्य अप्रोच (बिना लिबास)

def permutation(input):
    if len(input) == 1:
        return input if isinstance(input, list) else [input]

    result = []
    for i in range(len(input)):
        first = input[i]
        rest = input[:i] + input[i + 1:]
        rest_permutation = permutation(rest)
        for p in rest_permutation:
            result.append(first + p)
    return result

इनपुट एक स्ट्रिंग या एक सूची हो सकती है

print(permutation('abcd'))
print(permutation(['a', 'b', 'c', 'd']))

यह पूर्णांकों के साथ सूची के लिए काम नहीं करता है, उदाहरण के लिए। [1, 2, 3]रिटर्न[6, 6, 6, 6, 6, 6]
RK1

@ RK1, u यह कोशिश कर सकते हैंprint(permutation(['1','2','3']))
Tatsu

धन्यवाद कि काम करता है
RK1

3

अस्वीकरण: पैकेज लेखक द्वारा आकारहीन प्लग। :)

ट्रोटर पैकेज अधिकांश प्रयोगों से अलग है कि यह छद्म सूचियों है कि वास्तव में क्रमपरिवर्तन शामिल नहीं है बल्कि एक आदेश में क्रमपरिवर्तन और संबंधित पदों के बीच मैपिंग का वर्णन है, बहुत बड़ी क्रमपरिवर्तन की सूचियों 'के साथ काम करने के लिए यह संभव बनाने, दिखाया गया है उत्पन्न करता है में इस डेमो जो प्रदर्शन बहुत तात्कालिक संचालन और लुक-अप एक छद्म सूची 'वाले' वर्णमाला में पत्र के सभी क्रमपरिवर्तन में अधिक स्मृति का उपयोग कर या एक विशिष्ट वेब पेज से प्रसंस्करण के बिना,।

किसी भी मामले में, क्रमपरिवर्तन की सूची बनाने के लिए, हम निम्नलिखित कार्य कर सकते हैं।

import trotter

my_permutations = trotter.Permutations(3, [1, 2, 3])

print(my_permutations)

for p in my_permutations:
    print(p)

आउटपुट:

एक छद्म सूची जिसमें [1, 2, 3] के 6 3-क्रमपरिवर्तन हैं।
[१, २, ३]
[१, ३, २]
[३, १, २]
[३, २, १]
[२, ३, १]
[२, १, ३]

2

हर संभव क्रमपरिवर्तन उत्पन्न करें

मैं python3.4 का उपयोग कर रहा हूं:

def calcperm(arr, size):
    result = set([()])
    for dummy_idx in range(size):
        temp = set()
        for dummy_lst in result:
            for dummy_outcome in arr:
                if dummy_outcome not in dummy_lst:
                    new_seq = list(dummy_lst)
                    new_seq.append(dummy_outcome)
                    temp.add(tuple(new_seq))
        result = temp
    return result

परीक्षण के मामलों:

lst = [1, 2, 3, 4]
#lst = ["yellow", "magenta", "white", "blue"]
seq = 2
final = calcperm(lst, seq)
print(len(final))
print(final)

2

आप लोगों को खोज और प्रयोग के संभव घंटों को बचाने के लिए, यहाँ पायथन में गैर-पुनरावर्ती क्रमपरिवर्तन समाधान है जो नंबा (वी। 0.41 के रूप में) के साथ भी काम करता है:

@numba.njit()
def permutations(A, k):
    r = [[i for i in range(0)]]
    for i in range(k):
        r = [[a] + b for a in A for b in r if (a in b)==False]
    return r
permutations([1,2,3],3)
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

प्रदर्शन के बारे में एक धारणा देने के लिए:

%timeit permutations(np.arange(5),5)

243 µs ± 11.1 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
time: 406 ms

%timeit list(itertools.permutations(np.arange(5),5))
15.9 µs ± 8.61 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
time: 12.9 s

इसलिए इस संस्करण का उपयोग केवल तभी करें जब आपको इसे njitted फ़ंक्शन से कॉल करना होगा, अन्यथा इटर्टूल कार्यान्वयन को प्राथमिकता दें।


1

मैं इन पुनरावर्ती कार्यों के अंदर बहुत अधिक पुनरावृत्ति देख रहा हूं , बिल्कुल शुद्ध पुनरावृत्ति नहीं ...

तो आप में से जो एक भी लूप का पालन नहीं कर सकते, उनके लिए यहाँ एक सकल, पूरी तरह से अनावश्यक पूरी तरह से पुनरावर्ती समाधान है

def all_insert(x, e, i=0):
    return [x[0:i]+[e]+x[i:]] + all_insert(x,e,i+1) if i<len(x)+1 else []

def for_each(X, e):
    return all_insert(X[0], e) + for_each(X[1:],e) if X else []

def permute(x):
    return [x] if len(x) < 2 else for_each( permute(x[1:]) , x[0])


perms = permute([1,2,3])

1

एक और समाधान:

def permutation(flag, k =1 ):
    N = len(flag)
    for i in xrange(0, N):
        if flag[i] != 0:
            continue
        flag[i] = k 
        if k == N:
            print flag
        permutation(flag, k+1)
        flag[i] = 0

permutation([0, 0, 0])

0

मेरा अजगर समाधान:

def permutes(input,offset):
    if( len(input) == offset ):
        return [''.join(input)]

    result=[]        
    for i in range( offset, len(input) ):
         input[offset], input[i] = input[i], input[offset]
         result = result + permutes(input,offset+1)
         input[offset], input[i] = input[i], input[offset]
    return result

# input is a "string"
# return value is a list of strings
def permutations(input):
    return permutes( list(input), 0 )

# Main Program
print( permutations("wxyz") )

0
def permutation(word, first_char=None):
    if word == None or len(word) == 0: return []
    if len(word) == 1: return [word]

    result = []
    first_char = word[0]
    for sub_word in permutation(word[1:], first_char):
        result += insert(first_char, sub_word)
    return sorted(result)

def insert(ch, sub_word):
    arr = [ch + sub_word]
    for i in range(len(sub_word)):
        arr.append(sub_word[i:] + ch + sub_word[:i])
    return arr


assert permutation(None) == []
assert permutation('') == []
assert permutation('1')  == ['1']
assert permutation('12') == ['12', '21']

print permutation('abc')

आउटपुट: ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']


0

का उपयोग करते हुए Counter

from collections import Counter

def permutations(nums):
    ans = [[]]
    cache = Counter(nums)

    for idx, x in enumerate(nums):
        result = []
        for items in ans:
            cache1 = Counter(items)
            for id, n in enumerate(nums):
                if cache[n] != cache1[n] and items + [n] not in result:
                    result.append(items + [n])

        ans = result
    return ans
permutations([1, 2, 2])
> [[1, 2, 2], [2, 1, 2], [2, 2, 1]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.