दोहराव के साथ क्रमपरिवर्तन उत्पन्न करना


84

मैं itertools के बारे में जानता हूँ, लेकिन ऐसा लगता है कि यह केवल पुनरावृत्ति के बिना क्रमपरिवर्तन उत्पन्न कर सकता है।

उदाहरण के लिए, मैं 2 पासा के लिए सभी संभव पासा रोल उत्पन्न करना चाहूंगा। इसलिए मुझे पुनरावृत्तियों सहित [1, 2, 3, 4, 5, 6] के आकार के सभी क्रमपरिवर्तन की आवश्यकता है: (1, 1), (1, 2), (2, 1) ... आदि।

यदि संभव हो तो मैं इसे खरोंच से लागू नहीं करना चाहता

जवाबों:


144

आप कार्टेशियन प्रोडक्ट की तलाश में हैं

गणित में, एक कार्टेशियन उत्पाद (या उत्पाद सेट) दो सेटों का प्रत्यक्ष उत्पाद है।

आपके मामले में, यह {1, 2, 3, 4, 5, 6}x होगा {1, 2, 3, 4, 5, 6}itertoolsवहाँ आप मदद कर सकते हैं:

import itertools
x = [1, 2, 3, 4, 5, 6]
[p for p in itertools.product(x, repeat=2)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), 
 (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), 
 (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), 
 (5, 4), (5, 5), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]

एक यादृच्छिक पासा रोल पाने के लिए ( पूरी तरह से अक्षम तरीके से ):

import random
random.choice([p for p in itertools.product(x, repeat=2)])
(6, 3)

8
यह 2 पासा रोल प्राप्त करने का एक बेहद अक्षम तरीका है ... दो कॉल random.randintसरल और अधिक कुशल होंगे।
एरिक ओ लेबिगॉट

जब आप सभी संभावित जोड़े उत्पन्न नहीं करते हैं तो रैंडम पासा रोल बहुत तेज़ होगा: [random.randint (1,6) i for xrange (2)] में
liori

13
मैं वास्तव में यादृच्छिक रोल उत्पन्न करने की कोशिश नहीं कर रहा था, बस सभी संभावित रोल को सूचीबद्ध करने के लिए।
Bwmat


7

अजगर 2.7 और 3.1 में एक itertools.combinations_with_replacementफंक्शन है:

>>> list(itertools.combinations_with_replacement([1, 2, 3, 4, 5, 6], 2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), 
 (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6),
 (5, 5), (5, 6), (6, 6)]

12
यह समाधान संयोजन पर बाहर खो देता है (2, 1), (3, 2), (3, 1)और इसी तरह की ... सामान्य में यह सभी संयोजनों जहां दूसरा रोल पहले की तुलना में कम है बाहर छोड़ देता है।
होलीरो

1

इस मामले में, एक सूची समझ की विशेष रूप से आवश्यकता नहीं है।

दिया हुआ

import itertools as it


seq = range(1, 7)
r = 2

कोड

list(it.product(seq, repeat=r))

विवरण

जाहिर है, कार्टेशियन उत्पाद क्रमपरिवर्तन के सबसेट उत्पन्न कर सकता है। हालांकि, यह इस प्रकार है:

  • प्रतिस्थापन के साथ: सभी क्रमपरिवर्तन n उत्पादन आर के माध्यम सेproduct
  • प्रतिस्थापन के बिना: बाद वाले से फ़िल्टर करें

प्रतिस्थापन के साथ क्रमपरिवर्तन, एन आर

[x for x in it.product(seq, repeat=r)]

प्रतिस्थापन के बिना क्रमपरिवर्तन, एन!

[x for x in it.product(seq, repeat=r) if len(set(x)) == r]
# Equivalent
list(it.permutations(seq, r))  

नतीजतन, सभी जुझारू कार्यों से लागू किया जा सकता है product:

  • combinations_with_replacement से लागू किया गया product
  • combinationsसे लागू किया गया है permutations, जिसे product(ऊपर देखें) के साथ लागू किया जा सकता है

-1

मुझे लगता है कि मैंने केवल एक समाधान का उपयोग करके पाया lambdas, mapऔर reduce

product_function = lambda n: reduce(lambda x, y: x+y, map(lambda i: list(map(lambda j: (i, j), np.arange(n))), np.arange(n)), [])

अनिवार्य रूप से मैं पहला लैम्ब्डा फंक्शन मैप कर रहा हूं जिसने एक पंक्ति दी है, जो स्तंभों को प्रसारित करती है

list(map(lambda j: (i, j), np.arange(n)))

तब इसे नए लैम्बडा फ़ंक्शन के आउटपुट के रूप में उपयोग किया जाता है

lambda i:list(map(lambda j: (i, j), np.arange(n)))

जो सभी संभव पंक्तियों में मैप किया गया है

map(lambda i: list(map(lambda j: (i, j), np.arange(n))), np.arange(m))

और फिर हम सभी परिणामी सूचियों को एक में घटा देते हैं।

और भी बेहतर

दो अलग-अलग संख्याओं का उपयोग भी कर सकते हैं।

prod= lambda n, m: reduce(lambda x, y: x+y, map(lambda i: list(map(lambda j: (i, j), np.arange(m))), np.arange(n)), [])

-2

सबसे पहले, आप itertools.permutations (सूची) द्वारा लौटाए गए जनरेटर को पहले एक सूची में बदलना चाहते हैं। फिर दूसरी बात, आप डुप्लिकेट को हटाने के लिए सेट () का उपयोग कर सकते हैं जैसे कुछ नीचे:

def permutate(a_list):
    import itertools
    return set(list(itertools.permutations(a_list)))

1
जिसमें डुप्लिकेट शामिल नहीं है।
ब्योर्न लिंडक्विस्ट

1
ओपी स्पष्ट रूप से डुप्लिकेट चाहता है
लेवी लेसचेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.