2025, Sep 24 15:32

स्थिर इंडेक्स के साथ Python permutations कैसे बनाएं

Python में permutations को स्थिर इंडेक्स के साथ बनाना सीखें: एक और कई pinned positions के लिए itertools.permutations, साफ कोड, उदाहरण और प्रदर्शन टिप्स.

Python में permutations बनाना आसान है, लेकिन वास्तविक कामों में अक्सर कुछ सीमाएँ होती हैं: कुछ स्थान स्थिर रहने चाहिए, बाकी को अदल-बदल किया जा सकता है। यह गाइड पहले एक स्थिर इंडेक्स के साथ तरीका दिखाती है, और फिर itertools.permutations की मदद से इसे कई स्थिर इंडेक्स तक कैसे बढ़ाएँ, यह बताती है.

समस्या की रूपरेखा: एक स्थिर इंडेक्स के साथ permutation

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

from itertools import permutations
nums = [5, 6, 7, 9]
pin_idx = 2  # 7 को इंडेक्स 2 पर स्थिर रखें और [5, 6, 9] को permute करें
free_slice = nums[:pin_idx] + nums[pin_idx + 1:]
perm_iter = permutations(free_slice)
accum = []
for tup in perm_iter:
    accum.append(list(tup))
for candidate in accum:
    candidate.insert(pin_idx, nums[pin_idx])
print(accum)

यह हिलने-योग्य तत्वों के सभी permutations बनाता है और फिर स्थिर मान को उसकी मूल स्थिति में वापस डाल देता है। एक अकेले स्थिर इंडेक्स के लिए यह तरीका अच्छी तरह काम करता है.

अंदर क्या चल रहा है और यह क्यों काम करता है

मूल विचार सरल और प्रभावी है: स्थिर स्थानों पर मौजूद मानों को निकाल दें, बाकी का permutation बनाएं, और फिर स्थिर मानों को उनके मूल इंडेक्स पर वापस रख दें। क्योंकि permutations केवल घटाए गए सेट पर लागू होते हैं, स्थिर इंडेक्स पर मौजूद तत्व हिलते नहीं, और शेष मानों की सभी वैध व्यवस्थाएँ मिल जाती हैं.

जब इसे कई स्थिर इंडेक्स पर बढ़ाते हैं, तो यही सिद्धांत लागू होता है: जिन इंडेक्सों को छूना नहीं है उन्हें अलग करें, केवल बचे हुए मानों को permute करें, और हर उत्पन्न permutation में स्थिर मानों को उनके स्थान पर वापस रखें.

कई स्थिर इंडेक्स के लिए सामान्यीकृत समाधान

नीचे दिया गया फ़ंक्शन किसी भी स्थिर इंडेक्स सेट के लिए इसी पैटर्न को समेटता है। यह non-fixed हिस्से के लिए itertools.permutations से पुनर्व्यवस्थाएँ बनाता है और फिर स्थिर मानों को उनकी जगह पर वापस भर देता है.

from itertools import permutations
def lock_positions_perms(items: list, pinned_pos: list[int] | None = None) -> list[list]:
    """
    इनपुट आइटम्स के सभी permutations बनाएँ, जबकि
    निर्दिष्ट स्थानों के तत्व बिना बदले रहें।
    :param items: permute करने वाला अनुक्रम
    :param pinned_pos: वे इंडेक्स जिन्हें अपनी मूल स्थिति में रहना है
    :return: उन permutations की सूची जिनमें pinned स्थान सुरक्षित हों
    """
    pinned_pos = [] if pinned_pos is None else pinned_pos
    movable_vals = [val for idx, val in enumerate(items) if idx not in pinned_pos]
    all_arrangements = [list(t) for t in permutations(movable_vals)]
    for arrangement in all_arrangements:
        for pos in pinned_pos:
            arrangement.insert(pos, items[pos])
    return all_arrangements
print(lock_positions_perms(["a", "b", "c", "d", "e"], pinned_pos=[1, 3]))
# [['a', 'b', 'c', 'd', 'e'], ['a', 'b', 'e', 'd', 'c'], ['c', 'b', 'a', 'd', 'e'],
#  ['c', 'b', 'e', 'd', 'a'], ['e', 'b', 'a', 'd', 'c'], ['e', 'b', 'c', 'd', 'a']]

तरीका उसी single-index संस्करण जैसा है: non-pinned मानों को निकालें, उस उपसमुच्चय के सभी permutations बनाएं, और हर परिणाम में pinned मानों को उनके मौलिक इंडेक्स पर वापस डालें.

व्यवहार और समझौते: कुछ नोट्स

जैसा लिखा गया है, यह फ़ंक्शन itertools.permutations को तुरंत खपाकर पूरे परिणाम-सेट को मेमोरी में बना देता है। चाहें तो इसे इस तरह बदला जा सकता है कि यह pinned मानों को चलते-चलते जोड़ते हुए एक-एक परिणाम को yield करे, पूरी सूची लौटाने के बजाय। साथ ही, हर permutation के लिए दोबारा डालने का काम होने से यह तरीका सर्वाधिक कुशल नहीं भी हो सकता। कोई ज्यादा कुशल विकल्प स्पष्ट नहीं है, जब तक कि आप एक कस्टम permutation रूटीन न लिखें.

यह क्यों उपयोगी है

सीमाओं के साथ permutation करना तब काम आता है जब किसी डेटा लेआउट में कुछ एंकर हिल नहीं सकते, जबकि बाकी तत्वों को पूरी तरह आज़माया जा सकता है। यह पैटर्न कोड को साफ़ रखता है, इंडेक्सों के जरिए बाधाएँ बताने देता है, और मानक लाइब्रेरी के भरोसेमंद टूल: itertools.permutations का लाभ लेता है.

मुख्य बातें

जब स्थिर स्थानों के साथ permutations चाहिए हों, तो स्थिर और चलायमान हिस्सों को अलग करें, बाद वाले का permutation बनाएं, और स्थिर मानों को उनकी मूल जगह पर डालकर परिणामों को फिर से जोड़ दें। बड़े आउटपुट या स्ट्रीमिंग की ज़रूरत में, पूरी सूची बनाने के बजाय परिणामों को yield करने पर विचार करें। यदि बार-बार पुनः-डालने के कारण प्रदर्शन बाधा बने, तो मूल रूप से भिन्न permutation रणनीति की जरूरत पड़ेगी.

यह लेख StackOverflow पर प्रश्न (लेखक: Zeryab Hassan Kiani) और simon के उत्तर पर आधारित है।