কিভাবে একটি তালিকা সমস্ত অনুমতি উত্পন্ন?


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
আমি পুনরাবৃত্তি, গৃহীত উত্তরের সাথে একমত - আজ। যাইহোক, এটি এখনও একটি বিশাল কম্পিউটার বিজ্ঞানের সমস্যা হিসাবে স্থির রয়েছে। গৃহীত উত্তরটি ঘাটতিযুক্ত জটিলতার সাথে এই সমস্যার সমাধান করে (২ ^ এনএন = লেন (তালিকা)) বহুবর্ষে এটি সমাধান করুন (বা আপনি প্রমাণ করতে পারবেন না) :) "
ট্র্যাভেল

37
@ ফ্লিপএমসিএফ বহুগুণে এটি "সমাধান করা" কঠিন হবে, প্রদত্ত ঘটনাটিকে এমনকি আউটপুটটি গণনা করতে সময়িক সময় লাগে ... সুতরাং, না, এটি সম্ভব নয়।
থমাস

উত্তর:


488

পাইথন ২.6 দিয়ে শুরু করে (এবং যদি আপনি পাইথন 3 এ থাকেন) আপনার কাছে এর জন্য একটি স্ট্যান্ডার্ড-লাইব্রেরি সরঞ্জাম রয়েছে:itertools.permutations

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

যদি আপনি কোনও কারণে কোনও পুরনো পাইথন (<2.6) ব্যবহার করছেন বা এটি কীভাবে কাজ করে তা জানতে আগ্রহী হন তবে http://code.activestate.com/recips/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
তারা বৃহত তালিকাগুলি সহ পুনরাবৃত্তি
সীমাতেও

58
বিজিবিজি, ডিবিআর: এটি একটি জেনারেটর ব্যবহার করে, সুতরাং ফাংশনটি নিজেই স্মৃতি খায় না। এটি কীভাবে all_perms দ্বারা ফিরে আসা পুনরুক্তি গ্রাহক সে সম্পর্কে আপনার কাছে বাম (বলুন যে আপনি প্রতিটি পুনরুক্তি ডিস্কে লিখতে পারেন এবং স্মৃতি সম্পর্কে উদ্বিগ্ন না হয়ে)। আমি জানি এই পোস্টটি পুরাতন তবে আমি এখন যারা পড়ি তাদের সুবিধার জন্য এটি লিখছি। এছাড়াও এখন, সর্বোত্তম উপায় হ'ল অনেকের নির্দেশিত অনুসারে itertools.permutations () ব্যবহার করা।
জগতেশ চधा

18
নেই শুধু একটি জেনারেটর। এটি নেস্টেড জেনারেটর ব্যবহার করছে, যা স্পষ্ট না হলে ক্ষেত্রে প্রতিটি কল কল স্ট্যাক আপ করে। এটি ও (এন) মেমরি ব্যবহার করে, যা ভাল।
cdunn2001

1
PS: for i in range(len(elements))পরিবর্তে , আমি এটি স্থির করেছি for i in range(len(elements)+1)। আসলে, একক আউট উপাদান বিভিন্ন পদে elements[0:1]থাকতে পারে len(elements), ফলস্বরূপ, না len(elements)+1
এরিক হে লেবিগোট

339

এবং পাইথনে ২.6 এর পরে:

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

(জেনারেটর হিসাবে ফিরে এসেছে list(permutations(l))a তালিকা হিসাবে ফিরে আসতে ব্যবহার করুন ))


15
পাইথন 3
তেও

10
লক্ষ্য করুন যে এখানে একটি rপ্যারামিটার রয়েছে, উদাহরণস্বরূপ itertools.permutations([1,2,3], r=2), যা 2 টি উপাদান নির্বাচন করে সমস্ত সম্ভাব্য ক্রম উত্পাদন করতে পারে:[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
টোটো_টিকো

277

পাইথন সহ নিম্নলিখিত কোডগুলি ২. above এবং কেবলমাত্র উপরে

প্রথমত, আমদানি করুন 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)]

2
+1 টি! দস্তাবেজের লিঙ্ক: docs.python.org/2/library/itertools.html#itertools.permutations
প্রমোদ

`মুদ্রণ তালিকা (itertools.permutations ([1,2,3,4], 2)) ^ nt সিনট্যাক্স এরর: অবৈধ সিনট্যাক্স- ভিএস কোড ব্যবহার করে শুরু করা আমি কী ভুল করেছি? পয়েন্টারটি "তালিকার" টি "এর অধীনে ইশারা করছে
গাস

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')

কেন পুচ্ছ ছাপুন এবং তারপরে কেউ ফিরিয়ে দেবেন না? পরিবর্তে লেজ ফিরবে না কেন? যাইহোক কিছু ফেরত দিবে না কেন?
বাগম্যানট 123

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") করবে না কারণ আপনি কোনও স্ট্রিং পরিবর্তন করতে পারবেন না।

এই পাইথন বাস্তবায়ন হরোভিটস, সাহনি এবং রাজাসেকরান দ্বারা নির্মিত কম্পিউটার অ্যালগরিদম বইয়ে উপস্থাপিত অ্যালগরিদম দ্বারা অনুপ্রাণিত


আমি ধরে নিই কে দৈর্ঘ্য বা ক্রমান্বন। কে = 2 আউটপুটগুলির জন্য [1, 2, 3]। এটি (1, 2) (1, 3) (2, 1) (2, 3) (3, 1) (3, 2) হওয়া উচিত নয় ??
কনস্টান্টিনোস মোনাচোপ্লোস

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
এটি প্রযুক্তিগতভাবে পছন্দসই আউটপুট তৈরি করার সময়, আপনি এমন কিছু সমাধান করছেন যা ও (n g n) এ O (n lg n) হতে পারে - বড় সেটগুলির জন্য "সামান্য" অযোগ্য।
জেমস

3
@ জেমস: আপনি যে ও (এন লগ এন) দিয়েছেন তাতে আমি কিছুটা বিভ্রান্ত হয়ে পড়েছি: আদেশের সংখ্যা এন !, যা ইতিমধ্যে ও (এন লগ এন) এর চেয়ে অনেক বড়; সুতরাং, আমি দেখতে পাচ্ছি না যে সমাধান কীভাবে O (n লগ এন) হতে পারে। তবে এটি সত্য যে এই সমাধানটি ও (n ^ n) এ রয়েছে, যা এন! এর চেয়ে অনেক বড়, স্ট্রিলিংয়ের সান্নিধ্য থেকে পরিষ্কার is
এরিক হে লেবিগোট

9

আমি ফ্যাকটোরিয়াল নম্বর সিস্টেমের উপর ভিত্তি করে একটি অ্যালগরিদম ব্যবহার করেছি - দৈর্ঘ্য n এর তালিকার জন্য, আপনি প্রতিটি পর্যায়ে রেখে যাওয়া আইটেমগুলি থেকে আইটেমের মাধ্যমে প্রতিটি ক্রমবর্ধমান আইটেমটি একত্রিত করতে পারেন। আপনার প্রথম আইটেমটির জন্য এন পছন্দ আছে, দ্বিতীয়টির জন্য এন -1 এবং শেষের জন্য কেবল একটি, তাই আপনি সূচক হিসাবে ফ্যাক্টরিয়াল সংখ্যা পদ্ধতিতে একটি সংখ্যার অঙ্ক ব্যবহার করতে পারেন। এইভাবে 0 থেকে n! -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]]

এই পদ্ধতিটি পুনরাবৃত্তিযোগ্য নয়, তবে এটি আমার কম্পিউটারে সামান্য ধীর এবং এক্সরেঞ্জ একটি ত্রুটি উত্থাপন করে যখন এন! সি লম্বা পূর্ণসংখ্যায় রূপান্তরিত করতে খুব বড় (আমার জন্য n = 13)। আমার যখন এটির প্রয়োজন হয়েছিল তখন এটি যথেষ্ট ছিল, তবে এটি দীর্ঘ শটের দ্বারা কোনও itertools.permutations নয়।


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

জাজেনের উত্তরে যেমন প্রতিটি ক্রমশক্তিটির প্রথম উপাদানটি পুনরুক্ত করা যায়। এটি এইভাবে এই সমাধানটি লিখতে আরও দক্ষ:

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]

মৌলিক ধারণা 1st পদের জন্য অ্যারের মধ্যে সব উপাদান উপর যেতে, এবং তারপর 2nd অবস্থানে 1st জন্য নির্বাচিত উপাদান ছাড়া উপাদানের বাকি সব ওভার যেতে হয়, ইত্যাদি আপনার সাথে এটা করতে পারেন পুনরাবৃত্তির , যেখানে স্টপ মাপদণ্ড 1 টি উপাদানের অ্যারেতে চলেছে - এক্ষেত্রে আপনি সেই অ্যারেটি ফিরিয়ে দেন।

এখানে চিত্র বর্ণনা লিখুন


এটি আমার পক্ষে কাজ করে না _> ভ্যালু এরির: এই লাইনের জন্য আকারগুলি (0,) (2,) একসাথে সম্প্রচার করা যায়নি :perms = getPermutations(array[:i] + array[i+1:])
কে 1

@ আর কে 1 ইনপুটটি কী ছিল?
ডেভিড রেফেলি

আমি একটি numpyঅ্যারেতে যাচ্ছি _> getPermutations(np.array([1, 2, 3])), আমি দেখতে পাচ্ছি এটি একটি তালিকার জন্য কাজ করে, চমত্কার আর্গ হিসাবে ঠিক বিভ্রান্ত হয়ে পড়েছে array:)
কে 1

@ আর কে 1 এটি খুশী কাজ করে :-) তালিকাটি পাইথনের একটি কীওয়ার্ড, সুতরাং সাধারণত আপনার প্যারামিটারকে একটি কীওয়ার্ড বলা ভাল নয়, কারণ এটি এটি "ছায়া" করবে। সুতরাং আমি অ্যারে শব্দটি ব্যবহার করি, কারণ এটি তালিকার আসল কার্যকারিতা যা আমি ব্যবহার করছি - তাদের অ্যারের মতো। আমার ধারণা আমি যদি ডকুমেন্টেশন লিখি তবে আমি এটি স্পষ্ট করে বলব। এছাড়াও আমি বিশ্বাস করি যে মৌলিক "সাক্ষাত্কার" প্রশ্নগুলি নাম্বারের মতো বাহ্যিক প্যাকেজ ছাড়াই সমাধান করা উচিত।
ডেভিড রেফেলি

হাহা এটি সত্য, হ্যাঁ এটির সাথে এটি ব্যবহার করার চেষ্টা করা হয়েছিল numbaএবং গতির সাথে লোভী হয়েছিলেন তাই numpyঅ্যারে দিয়ে একচেটিয়াভাবে এটি ব্যবহার করার চেষ্টা করেছিলেন
কে 1

4

কর্মক্ষমতা, একটি numpy সমাধান দ্বারা অনুপ্রাণিত Knuth , (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, :]

বড় ব্লকের মেমরির অনুলিপি করা সময় সাশ্রয় করে - এটি এর চেয়ে 20 গুণ বেশি দ্রুত 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

অন্য কোনও পদ্ধতি (libs ছাড়া)

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]
কে 1

@ RK1, U- এই চেষ্টা করতে পারেনprint(permutation(['1','2','3']))
Tatsu

ধন্যবাদ যে কাজ করে
কে 1

3

দাবি অস্বীকার: প্যাকেজ লেখকের দ্বারা নিরাকার প্লাগ। :)

Trotter প্যাকেজ সবচেয়ে বাস্তবায়নের থেকে ভিন্ন যে এটা ছদ্ম তালিকা যা আসলে একাধিক বিন্যাসন থাকে না বরং একটি ক্রম মধ্যে একাধিক বিন্যাসন এবং নিজ নিজ অবস্থানের মধ্যে ম্যাপিং বর্ণনা, খুব বড় একাধিক বিন্যাসন 'তালিকা' দিয়ে কাজ করা সম্ভব করা, দেখানো হয়েছে উত্পন্ন মধ্যে এই ডেমো যা সঞ্চালিত চমত্কার ক্ষণিক অপারেশন এবং চেহারা আপগুলি একটি সিউডো-তালিকা 'ধারণকারী' বর্ণমালায় অক্ষর সব একাধিক বিন্যাসন মধ্যে আরো মেমরি ব্যবহার বা একটি টিপিক্যাল ওয়েবপৃষ্ঠাটি চেয়ে প্রক্রিয়াকরণের ছাড়া।

যে কোনও ক্ষেত্রে, ক্রমানুসারে একটি তালিকা তৈরি করতে, আমরা নিম্নলিখিতটি করতে পারি।

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-ক্রমানুসারে একটি ছদ্ম তালিকা রয়েছে।
[১, ২, ৩]
[১, ৩, ২]
[3, 1, 2]
[3, 2, 1]
[২, ৩, ১]
[২, ১, ৩]

2

সমস্ত সম্ভাব্য ক্রম উত্পন্ন করুন

আমি পাইথন ৩.৪ ব্যবহার করছি:

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

সুতরাং এই সংস্করণটি কেবল তখনই ব্যবহার করুন যদি আপনাকে এটিকে কল করতে হয় নিজিটেড ফাংশন থেকে, অন্যথায় এটির্টোলগুলি বাস্তবায়ন পছন্দ করুন।


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')

আউটপুট: ['এবিসি', 'এসিবি', 'ব্যাক', 'বিসিএ', 'ক্যাব', 'সিবিএ']


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]]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.