एक सेट के सभी सबसेट कैसे प्राप्त करें? (सत्ता स्थापित)


103

एक सेट दिया

{0, 1, 2, 3}

मैं सबसेट कैसे बना सकता हूं:

[set(),
 {0},
 {1},
 {2},
 {3},
 {0, 1},
 {0, 2},
 {0, 3},
 {1, 2},
 {1, 3},
 {2, 3},
 {0, 1, 2},
 {0, 1, 3},
 {0, 2, 3},
 {1, 2, 3},
 {0, 1, 2, 3}]

जवाबों:


145

पायथन itertoolsपेज में इसके powersetलिए एक नुस्खा है:

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

आउटपुट:

>>> list(powerset("abcd"))
[(), ('a',), ('b',), ('c',), ('d',), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd'), ('a', 'b', 'c', 'd')]

यदि आप शुरुआत में उस खाली नल को पसंद नहीं करते हैं, तो आप 0-लंबाई संयोजन से बचने के rangeलिए केवल कथन बदल सकते हैं range(1, len(s)+1)


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

क्यों s = list(iterable)जरूरी है?
जैक स्टीवंस

@JackStevens क्योंकि पुनरावृत्तियां पुन: प्रयोज्य नहीं हैं और इन्हें __len__लागू करने की आवश्यकता नहीं है ; powerset((n for n in range(3)))सूची लपेटे बिना प्रयास करें ।
फहराना

1
बड़े तार के लिए, यह बहुत मेमोरी खाएगा!
NoobEditor

1
@AlexandreHuat: रंग आलसी क्रम हैं, पुनरावृत्त नहीं। बिना भीpowerset(range(3)) ठीक काम करेगा । s = list(iterable)
user2357112 मोनिका

50

यहां एक पावरसेट के लिए अधिक कोड है। यह खरोंच से लिखा गया है:

>>> def powerset(s):
...     x = len(s)
...     for i in range(1 << x):
...         print [s[j] for j in range(x) if (i & (1 << j))]
...
>>> powerset([4,5,6])
[]
[4]
[5]
[4, 5]
[6]
[4, 6]
[5, 6]
[4, 5, 6]

मार्क रुशकॉफ़ की टिप्पणी यहां लागू है: "यदि आप शुरुआत में उस खाली ट्यूपल को पसंद नहीं करते हैं, तो" आप 0-लंबाई संयोजन से बचने के लिए रेंज स्टेटमेंट को रेंज (1, len (s) +1) में बदल सकते हैं। ", मेरे मामले को छोड़कर आप बदल for i in range(1 << x)जाते हैं for i in range(1, 1 << x)


वर्षों बाद इस पर लौटते हुए, अब मैं इसे इस तरह लिखूंगा:

def powerset(s):
    x = len(s)
    masks = [1 << i for i in range(x)]
    for i in range(1 << x):
        yield [ss for mask, ss in zip(masks, s) if i & mask]

और फिर परीक्षण कोड इस तरह दिखेगा, कहते हैं:

print(list(powerset([4, 5, 6])))

उपयोग करने का yieldअर्थ है कि आपको स्मृति के एक टुकड़े में सभी परिणामों की गणना करने की आवश्यकता नहीं है। मुख्य लूप के बाहर मास्क लगाना एक सार्थक अनुकूलन माना जाता है।


6
यह एक रचनात्मक जवाब है। हालाँकि, मैंने इसे मार्क रुशकॉफ से तुलना करने के लिए समय का उपयोग करके मापा और देखा कि यह काफी धीमा था। 100 बार 16 वस्तुओं का पावर सेट उत्पन्न करने के लिए, मेरा माप 0.55 बनाम 15.6 था।
सीसर

19

यदि आप एक त्वरित उत्तर की तलाश कर रहे हैं, तो मैंने बस "पायथन पावर सेट" को Google पर खोजा और इसके साथ आया: पायथन पावर सेट जेनरेटर

उस पृष्ठ के कोड से कॉपी-पेस्ट यहां दिया गया है:

def powerset(seq):
    """
    Returns all the subsets of this set. This is a generator.
    """
    if len(seq) <= 1:
        yield seq
        yield []
    else:
        for item in powerset(seq[1:]):
            yield [seq[0]]+item
            yield item

इसका उपयोग इस तरह किया जा सकता है:

 l = [1, 2, 3, 4]
 r = [x for x in powerset(l)]

अब r उन सभी तत्वों की एक सूची है जिन्हें आप चाहते थे, और जिन्हें छांटा और मुद्रित किया जा सकता है:

r.sort()
print r
[[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 4], [1, 3], [1, 3, 4], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], [3], [3, 4], [4]]

1
इनपुट के रूप में एक खाली सरणी के मामले में, उपरोक्त कोड वापस आ जाएगा [[][]], यह तय करने के लिए कि लंबाई जांच के लिए बस अलग-अलग मामले हैंif len(seq) == 0: yield [] elif len(seq) == 1: yield seq yield []
आयुष

3
संदर्भ के लिए, मैंने समयसीमा का उपयोग करके इसे (आयुष के संपादन के साथ) मापा और इसकी तुलना मार्क रुशकॉफ़ के उत्तर में पॉवरसेट नुस्खा से की। मेरी मशीन पर, 100 बार 16 वस्तुओं के अधिकार को उत्पन्न करने के लिए, इस एल्गोरिथ्म में 1.36 सेकंड लगे, जबकि रुशाखॉफ ने 0.55 लिया।
सीज़र

इसके लिए समय की जटिलता क्या होगी?
कोडक्वेस्टर

13
def powerset(lst):
    return reduce(lambda result, x: result + [subset + [x] for subset in result],
                  lst, [[]])

8

एक अधिकार का परिशोधन है:

def powerset(seq):
    """
    Returns all the subsets of this set. This is a generator.
    """
    if len(seq) <= 0:
        yield []
    else:
        for item in powerset(seq[1:]):
            yield [seq[0]]+item
            yield item

8

टीएल; डीआर (सरलीकरण पर सीधे जाएं)

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

def power_set(A):
    """A is an iterable (list, tuple, set, str, etc)
    returns a set which is the power set of A."""
    length = len(A)
    l = [a for a in A]
    ps = set()

    for i in range(2 ** length):
        selector = f'{i:0{length}b}'
        subset = {l[j] for j, bit in enumerate(selector) if bit == '1'}
        ps.add(frozenset(subset))

    return ps

यदि आप चाहते हैं कि आपके उत्तर में पोस्ट किया गया आउटपुट इसी का उपयोग करें:

>>> [set(s) for s in power_set({1, 2, 3, 4})]
[{3, 4},
 {2},
 {1, 4},
 {2, 3, 4},
 {2, 3},
 {1, 2, 4},
 {1, 2},
 {1, 2, 3},
 {3},
 {2, 4},
 {1},
 {1, 2, 3, 4},
 set(),
 {1, 3},
 {1, 3, 4},
 {4}]

व्याख्या

यह ज्ञात है कि पावर सेट के तत्वों की संख्या है 2 ** len(A), ताकि forलूप में स्पष्ट रूप से देखा जा सके ।

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

selectorइस एल्गोरिथ्म में महत्वपूर्ण है। ध्यान दें कि selectorइनपुट सेट के समान लंबाई है, और इसे संभव बनाने के लिए यह पैडिंग के साथ एक एफ-स्ट्रिंग का उपयोग कर रहा है। मूल रूप से, यह मुझे उन तत्वों का चयन करने की अनुमति देता है जो प्रत्येक पुनरावृत्ति के दौरान प्रत्येक सबसेट में जोड़े जाएंगे। मान लें कि इनपुट सेट में 3 तत्व हैं {0, 1, 2}, इसलिए चयनकर्ता 0 और 7 (समावेशी) के बीच मान लेगा, जो बाइनरी में हैं:

000 # 0
001 # 1
010 # 2
011 # 3
100 # 4
101 # 5
110 # 6
111 # 7

तो, प्रत्येक बिट एक संकेतक के रूप में सेवा कर सकता है यदि मूल सेट का एक तत्व जोड़ा जाना चाहिए या नहीं। द्विआधारी संख्याओं को देखें, और प्रत्येक संख्या को सुपर सेट के एक तत्व के रूप में सोचें जिसमें 1इसका मतलब है कि सूचकांक में एक तत्व jजोड़ा जाना चाहिए, और 0इसका मतलब है कि इस तत्व को नहीं जोड़ा जाना चाहिए।

मैं प्रत्येक पुनरावृत्ति पर एक सबसेट उत्पन्न करने के लिए एक सेट कॉम्प्रिहेंशन का उपयोग कर रहा हूं, और मैं इस सबसेट को एक में परिवर्तित करता frozensetहूं ताकि मैं इसे ps(पावर सेट) में जोड़ सकूं । अन्यथा, मैं इसे जोड़ नहीं पाऊंगा क्योंकि पायथन में एक सेट में केवल अपरिवर्तनीय वस्तुएं होती हैं।

सरलीकरण

आप कुछ अजगर समझ का उपयोग करके कोड को सरल बना सकते हैं, ताकि आप छोरों के लिए छुटकारा पा सकें। आप सूचकांक zipका उपयोग करने से बचने के लिए भी उपयोग कर सकते हैं jऔर कोड निम्नलिखित के रूप में समाप्त हो जाएगा:

def power_set(A):
    length = len(A)
    return {
        frozenset({e for e, b in zip(A, f'{i:{length}b}') if b == '1'})
        for i in range(2 ** length)
    }

बस। इस एल्गोरिथ्म को जो मैं पसंद करता हूं वह यह है कि यह दूसरों की तुलना में स्पष्ट और अधिक सहज है क्योंकि यह itertoolsअपेक्षा के अनुरूप काम करने के बावजूद काफी जादुई लगता है।


5
def get_power_set(s):
  power_set=[[]]
  for elem in s:
    # iterate over the sub sets so far
    for sub_set in power_set:
      # add a new subset consisting of the subset at hand added elem
      power_set=power_set+[list(sub_set)+[elem]]
  return power_set

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

get_power_set([1,2,3])

प्राप्ति

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

1
लूप में एक लूप वेरिएबल ( power_set) को संशोधित करना जो इसे नियंत्रित करता है एक बहुत ही संदिग्ध अभ्यास है। उदाहरण के लिए, मान लीजिए कि आपने प्रस्तावित चर-संशोधित कोड के बजाय यह लिखा है power_set += [list(sub_set)+[elem]]:। फिर लूप समाप्त नहीं होता है।
ह्यूजब्रोएन

5

मैंने निम्नलिखित एल्गोरिथ्म को बहुत स्पष्ट और सरल पाया है:

def get_powerset(some_list):
    """Returns all subsets of size 0 - len(some_list) for some_list"""
    if len(some_list) == 0:
        return [[]]

    subsets = []
    first_element = some_list[0]
    remaining_list = some_list[1:]
    # Strategy: get all the subsets of remaining_list. For each
    # of those subsets, a full subset list will contain both
    # the original subset as well as a version of the subset
    # that contains first_element
    for partial_subset in get_powerset(remaining_list):
        subsets.append(partial_subset)
        subsets.append(partial_subset[:] + [first_element])

    return subsets

दूसरा तरीका यह है कि कोई भी nबिट्स के पास सभी बाइनरी संख्याओं को जनरेट करके एक पॉवरसेट तैयार कर सकता है । एक शक्ति के रूप में nअंकों के साथ संख्या की मात्रा निर्धारित है 2 ^ n। इस एल्गोरिथ्म का सिद्धांत यह है कि एक उपसमुच्चय में एक तत्व मौजूद हो सकता है या नहीं हो सकता है क्योंकि बाइनरी अंक एक या शून्य हो सकता है लेकिन दोनों नहीं।

def power_set(items):
    N = len(items)
    # enumerate the 2 ** N possible combinations
    for i in range(2 ** N):
        combo = []
        for j in range(N):
            # test bit jth of integer i
            if (i >> j) % 2 == 1:
                combo.append(items[j])
        yield combo

मुझे दोनों एल्गोरिदम मिले जब मैं MITx ले रहा था: 6.00.2x कम्प्यूटेशनल थिंकिंग और डेटा साइंस का परिचय, और मुझे लगता है कि यह समझने के लिए सबसे आसान एल्गोरिदम में से एक है जिसे मैंने देखा है।


3

मैं सिर्फ सबसे समझदार समाधान प्रदान करना चाहता था, विरोधी कोड-गोल्फ संस्करण।

from itertools import combinations

l = ["x", "y", "z", ]

def powerset(items):
    combo = []
    for r in range(len(items) + 1):
        #use a list to coerce a actual list from the combinations generator
        combo.append(list(combinations(items,r)))
    return combo

l_powerset = powerset(l)

for i, item in enumerate(l_powerset):
    print "All sets of length ", i
    print item

परिणाम

लंबाई के सभी सेट 0

[()]

लंबाई 1 के सभी सेट

[('x',), ('y',), ('z',)]

लंबाई 2 के सभी सेट

[('x', 'y'), ('x', 'z'), ('y', 'z')]

लंबाई 3 के सभी सेट

[('x', 'y', 'z')]

अधिक देखने के लिए itertools डॉक्स , पावर सेट पर विकिपीडिया प्रविष्टि भी


2

बस एक त्वरित बिजली सेट पुनश्चर्या!

एक सेट एक्स का पावर सेट, खाली सेट सहित एक्स के सभी सबसेट का सेट है

उदाहरण सेट X = (ए, बी, सी)

पावर सेट = {{ए, बी, सी}, {ए, बी}, {ए, सी}, {बी, सी}, {ए}, {बी}, {सी}, {}}।

यहां पावर सेट खोजने का एक और तरीका है:

def power_set(input):
    # returns a list of all subsets of the list a
    if (len(input) == 0):
        return [[]]
    else:
        main_subset = [ ]
        for small_subset in power_set(input[1:]):
            main_subset += [small_subset]
            main_subset += [[input[0]] + small_subset]
        return main_subset

print(power_set([0,1,2,3]))

स्रोत का पूरा श्रेय


2

खाली सेट के साथ, जो सभी सबसेट का हिस्सा है, आप इसका उपयोग कर सकते हैं:

def subsets(iterable):
    for n in range(len(iterable) + 1):
        yield from combinations(iterable, n)

2

यह बहुत स्वाभाविक रूप से किया जा सकता है itertools.product:

import itertools

def powerset(l):
    for sl in itertools.product(*[[[], [i]] for i in l]):
        yield {j for i in sl for j in i}

1
इस सवाल का सबसे सुरुचिपूर्ण जवाब
आर्थर बी।

1

एक सरल तरीका 2 के पूरक अंकगणित के तहत पूर्णांकों के आंतरिक प्रतिनिधित्व का दोहन करना होगा।

पूर्णांक के बाइनरी प्रतिनिधित्व {000, 001, 010, 011, 100, 101, 110, 111} के रूप में 0 से 7 तक की संख्या के लिए है। पूर्णांक काउंटर मान के लिए, 1 को संग्रह में इसी तत्व के समावेश के रूप में और '0' पर विचार करें। अपवर्जन के रूप में हम गिनती क्रम के आधार पर सबसेट उत्पन्न कर सकते हैं। से नंबर जेनरेट करने होंगे0 करनी होती हैं pow(2,n) -1जहाँ से n सरणी की लंबाई यानी बाइनरी प्रतिनिधित्व में बिट्स की संख्या होती है।

इस पर आधारित एक सरल सबसेट जेनरेटर फंक्शन को नीचे लिखा जा सकता है। यह मूल रूप से निर्भर करता है

def subsets(array):
    if not array:
        return
    else:
        length = len(array)
        for max_int in range(0x1 << length):
            subset = []
            for i in range(length):
                if max_int & (0x1 << i):
                    subset.append(array[i])
            yield subset

और फिर इसका उपयोग किया जा सकता है

def get_subsets(array):
    powerset = []
    for i in subsets(array):
        powerser.append(i)
    return powerset

परिक्षण

स्थानीय फ़ाइल में निम्नलिखित जोड़ना

if __name__ == '__main__':
    sample = ['b',  'd',  'f']

    for i in range(len(sample)):
        print "Subsets for " , sample[i:], " are ", get_subsets(sample[i:])

निम्नलिखित उत्पादन देता है

Subsets for  ['b', 'd', 'f']  are  [[], ['b'], ['d'], ['b', 'd'], ['f'], ['b', 'f'], ['d', 'f'], ['b', 'd', 'f']]
Subsets for  ['d', 'f']  are  [[], ['d'], ['f'], ['d', 'f']]
Subsets for  ['f']  are  [[], ['f']]

यह स्थिरता या पठनीयता के बारे में व्यावहारिक नहीं हो सकता है, लेकिन इसने मेरे दिमाग को उड़ा दिया। साझा करने के लिए धन्यवाद, स्मार्ट समाधान!
लोरी

1

इनमें से लगभग सभी उत्तर के listबजाय उपयोग करते हैं set, जो मुझे थोड़ा सा धोखा जैसा लगा। इसलिए, जिज्ञासा से बाहर मैंने एक सरल संस्करण को वास्तव में करने की कोशिश की setऔर अन्य "नए पायथन" लोगों के लिए संक्षेप में प्रस्तुत किया।

मैंने पाया कि पायथन के सेट कार्यान्वयन से निपटने में कुछ विषमताएँ हैं । मेरे लिए मुख्य आश्चर्य खाली सेटों को संभालना था। यह रूबी के सेट कार्यान्वयन के विपरीत है , जहां मैं बस कर सकता हूं Set[Set[]]और Setएक खाली एक प्राप्त कर सकता हूं Set, इसलिए मैंने इसे शुरू में थोड़ा भ्रमित किया।

समीक्षा करने के लिए, एस के powersetसाथ करने में set, मुझे दो समस्याओं का सामना करना पड़ा:

  1. set()एक पुनरावृत्ति लेता है, इसलिए set(set())वापस आ जाएगा set() क्योंकि खाली सेट चलने योग्य खाली है (मुझे लगता है :)
  2. एक सेट प्राप्त करने के लिए, set({set()})धोने योग्य नहीं होने केset.add(set) कारण और काम नहीं करेगाset()

दोनों मुद्दों को हल करने के लिए, मैंने इसका उपयोग किया frozenset() इसका , जिसका अर्थ है कि मुझे वह नहीं मिलता जो मैं चाहता हूं (प्रकार का शाब्दिक अर्थ है set), लेकिन समग्र रूप से उपयोग करता है set

def powerset(original_set):
  # below gives us a set with one empty set in it
  ps = set({frozenset()}) 
  for member in original_set:
    subset = set()
    for m in ps:
      # to be added into subset, needs to be
      # frozenset.union(set) so it's hashable
      subset.add(m.union(set([member]))
    ps = ps.union(subset)
  return ps

नीचे हमें 2 get (16) frozensetसही ढंग से आउटपुट के रूप में मिलता है:

In [1]: powerset(set([1,2,3,4]))
Out[2]:
{frozenset(),
 frozenset({3, 4}),
 frozenset({2}),
 frozenset({1, 4}),
 frozenset({3}),
 frozenset({2, 3}),
 frozenset({2, 3, 4}),
 frozenset({1, 2}),
 frozenset({2, 4}),
 frozenset({1}),
 frozenset({1, 2, 4}),
 frozenset({1, 3}),
 frozenset({1, 2, 3}),
 frozenset({4}),
 frozenset({1, 3, 4}),
 frozenset({1, 2, 3, 4})}

वहाँ एक करने के लिए कोई रास्ता नहीं है के रूप में setकी setपायथन में, आप इन चालू करना चाहते हैं frozensetमें रों setरों, आप एक में उन्हें वापस मैप करने के लिए होगा list( list(map(set, powerset(set([1,2,3,4])))) ) या इसके बाद संशोधित करें।


1

शायद सवाल पुराना हो रहा है, लेकिन मुझे उम्मीद है कि मेरा कोड किसी की मदद करेगा।

def powSet(set):
    if len(set) == 0:
       return [[]]
    return addtoAll(set[0],powSet(set[1:])) + powSet(set[1:])

def addtoAll(e, set):
   for c in set:
       c.append(e)
   return set

ईव, पुनरावृत्ति! =)
étale-cohomology

शायद सबसे कुशल तरीका नहीं है, लेकिन पुनरावर्ती रास्ता देखना हमेशा दिलचस्प होता है!
लिसेंड्रो डी मेओ

1

powerset()पैकेज से फ़ंक्शन का उपयोग करें more_itertools

चलने योग्य के सभी संभव सबसेट उपज देता है

>>> list(powerset([1, 2, 3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

यदि आप सेट चाहते हैं, तो उपयोग करें:

list(map(set, powerset(iterable)))

1
इतने सारे लोग यहां पहिया को फिर से मजबूत कर रहे हैं, IMHO यह सबसे अच्छा जवाब है क्योंकि यह पहले से ही आपकी निर्भरता में हो सकता है क्योंकि यह कई सामान्य पुस्तकालयों द्वारा आवश्यक है, जैसे कि pytest। पुस्तकालयों
.io

1

पुनरावृत्ति के साथ सभी सबसेट प्राप्त करना। पागल-गधा एक-लाइनर

from typing import List

def subsets(xs: list) -> List[list]:
    return subsets(xs[1:]) + [x + [xs[0]] for x in subsets(xs[1:])] if xs else [[]]

हास्केल समाधान पर आधारित है

subsets :: [a] -> [[a]]
subsets [] = [[]]
subsets (x:xs) = map (x:) (subsets xs) ++ subsets xs

NameError: name 'List' is not defined
4LegsDrivenCat

@ 4LegsDrivenCat मैंने Listआयात जोड़ा है
Paweł Rubin

1
def findsubsets(s, n): 
    return list(itertools.combinations(s, n)) 

def allsubsets(s) :
    a = []
    for x in range(1,len(s)+1):
        a.append(map(set,findsubsets(s,x)))      
    return a

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

1

आप इसे इस तरह से कर सकते हैं:

def powerset(x):
    m=[]
    if not x:
        m.append(x)
    else:
        A = x[0]
        B = x[1:]
        for z in powerset(B):
            m.append(z)
            r = [A] + z
            m.append(r)
    return m

print(powerset([1, 2, 3, 4]))

आउटपुट:

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

क्या मैं सुझाव दे सकता हूं कि कोड समाधान पोस्ट करते समय, एक विस्तृत विवरण देने के लिए पर्याप्त हो कि कोड क्या कर रहा है और आप किसी समस्या को हल करने के लिए इस या उस पद्धति का उपयोग क्यों करते हैं। नए कोडर्स को सिर्फ एक कोड ब्लॉक को नहीं देखना चाहिए और यह जानना चाहिए कि कोड क्या कर रहा है और क्यों कर रहा है। धन्यवाद और Stackoverflow में आपका स्वागत है।
योकाई

वास्तव में प्रभावशाली और पुनरावर्ती उत्तर।
जॉन

1

मुझे पता है कि यह बहुत देर हो चुकी है

कई अन्य समाधान पहले से ही हैं लेकिन फिर भी ...

def power_set(lst):
    pw_set = [[]]

    for i in range(0,len(lst)):
        for j in range(0,len(pw_set)):
            ele = pw_set[j].copy()
            ele = ele + [lst[i]]
            pw_set = pw_set + [ele]

    return pw_set

0

यह जंगली है क्योंकि इनमें से कोई भी उत्तर वास्तव में एक वास्तविक अजगर सेट की वापसी प्रदान नहीं करता है। यहाँ एक गन्दा कार्यान्वयन है जो एक ऐसा अधिकार देगा जो वास्तव में पायथन है set

test_set = set(['yo', 'whatup', 'money'])
def powerset( base_set ):
    """ modified from pydoc's itertools recipe shown above"""
    from itertools import chain, combinations
    base_list = list( base_set )
    combo_list = [ combinations(base_list, r) for r in range(len(base_set)+1) ]

    powerset = set([])
    for ll in combo_list:
        list_of_frozensets = list( map( frozenset, map( list, ll ) ) ) 
        set_of_frozensets = set( list_of_frozensets )
        powerset = powerset.union( set_of_frozensets )

    return powerset

print powerset( test_set )
# >>> set([ frozenset(['money','whatup']), frozenset(['money','whatup','yo']), 
#        frozenset(['whatup']), frozenset(['whatup','yo']), frozenset(['yo']),
#        frozenset(['money','yo']), frozenset(['money']), frozenset([]) ])

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


अच्छा बिंदु, लेकिन ओपी आउटपुट के रूप में सेट की एक सूची चाहता है, इसलिए (पायथन 3 में) आप कर सकते हैं [*map(set, chain.from_iterable(combinations(s, r) for r in range(len(s)+1)))]; यदि आप चाहें तो फ़ंक्शन का arg mapहो सकता है frozenset
PM 2Ring

0

यहाँ मेरा त्वरित कार्यान्वयन संयोजनों का उपयोग कर रहा है लेकिन केवल बिल्ट-इन का उपयोग कर रहा है।

def powerSet(array):
    length = str(len(array))
    formatter = '{:0' + length + 'b}'
    combinations = []
    for i in xrange(2**int(length)):
        combinations.append(formatter.format(i))
    sets = set()
    currentSet = []
    for combo in combinations:
        for i,val in enumerate(combo):
            if val=='1':
                currentSet.append(array[i])
        sets.add(tuple(sorted(currentSet)))
        currentSet = []
    return sets

0

सेट के रूप में रेंज n में सभी सबसेट:

n = int(input())
l = [i for i in range (1, n + 1)]

for number in range(2 ** n) :
    binary = bin(number)[: 1 : -1]
    subset = [l[i] for i in range(len(binary)) if binary[i] == "1"]
    print(set(sorted(subset)) if number > 0 else "{}")

0
import math    
def printPowerSet(set,set_size): 
    pow_set_size =int(math.pow(2, set_size))
    for counter in range(pow_set_size):
    for j in range(set_size):  
        if((counter & (1 << j)) > 0):
            print(set[j], end = "")
    print("")
set = ['a', 'b', 'c']
printPowerSet(set,3)

0

प्रश्न का एक रूपांतर, एक ऐसी पुस्तक है जिसे मैं "डिस्कवरी कंप्यूटर साइंस: इंटरडिसिप्लिनरी प्रॉब्लम्स, प्रिंसिपल्स और पायथन प्रोग्रामिंग 2015 पुस्तक" पर देखता हूं। उस अभ्यास में 10.2.11, इनपुट सिर्फ एक पूर्णांक संख्या है, और आउटपुट पावर सेट होना चाहिए। यहाँ मेरा पुनरावर्ती समाधान है (किसी और चीज़ का उपयोग नहीं बल्कि मूल python3)

def powerSetR(n):
    assert n >= 0
    if n == 0:
        return [[]]
    else:
        input_set = list(range(1, n+1)) # [1,2,...n]
        main_subset = [ ]
        for small_subset in powerSetR(n-1):
            main_subset += [small_subset]
            main_subset += [ [input_set[-1]] + small_subset]
        return main_subset

superset = powerSetR(4)
print(superset)       
print("Number of sublists:", len(superset))

और आउटपुट है

[[], [४], [३], [४, ३], [२], [४, २], [३, २], [४, ३, २], [१], [४], १ ], [३, १], [४, ३, १], [२, १], [४, २, १], [३, २, १], [४, ३, २, १]] की संख्या उदात्त: १६


0

मैं more_itertools.powersetसमारोह में नहीं आया था और वह इसका उपयोग करने की सिफारिश करेगा। मैं आउटपुट के डिफ़ॉल्ट ऑर्डर का उपयोग न करने की सलाह भी देता हूं itertools.combinations, अक्सर इसके बजाय आप दूरी को कम करना चाहते हैं पदों के बीच की और उन दोनों के बीच कम दूरी वाले आइटमों के सबसेट को छाँटना चाहते हैं / उन दोनों के बीच की बड़ी दूरी वाली वस्तुओं से पहले।

itertoolsव्यंजनों पेज का उपयोग करता है पता चलता हैchain.from_iterable

  • ध्यान दें कि rयहाँ एक द्विपद गुणांक के निचले हिस्से के लिए मानक संकेतन से मेल खाता है , sआमतौर पर nगणित ग्रंथों में और कैलकुलेटर पर कहा जाता है ("एन चुनें आर")
def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

यहां अन्य उदाहरण [1,2,3,4]इस तरह से अधिकार देते हैं कि 2-ट्यूपल "लेक्सिकोग्राफिक" क्रम में सूचीबद्ध होते हैं (जब हम संख्याओं को पूर्णांक के रूप में प्रिंट करते हैं)। अगर मैं इसके साथ संख्याओं के बीच की दूरी (यानी अंतर) लिखता हूं, तो यह मेरी बात को दर्शाता है:

121
132
143
231
242
341

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

121
231
341
132
242
143

यहां संख्याओं का उपयोग करने से यह ऑर्डरिंग 'गलत' हो जाता है, लेकिन उदाहरण के लिए उन अक्षरों पर विचार करें जो ["a","b","c","d"]यह स्पष्ट है कि इस क्रम में अधिकार प्राप्त करने के लिए यह उपयोगी क्यों हो सकता है:

ab ⇒ 1
bc ⇒ 1
cd ⇒ 1
ac ⇒ 2
bd ⇒ 2
ad ⇒ 3

यह प्रभाव अधिक वस्तुओं के साथ अधिक स्पष्ट होता है, और मेरे उद्देश्यों के लिए, यह इस बीच अंतर करता है कि शक्तियों के सूचकांक की सीमाओं का सार्थक वर्णन किया जा सके।

( ग्रे कोड्स पर बहुत कुछ लिखा है कॉम्बिनेटरिक्स में एल्गोरिदम के आउटपुट ऑर्डर के लिए , मैं इसे एक साइड इश्यू के रूप में नहीं देखता हूं)।

मैंने वास्तव में सिर्फ एक सम्मिलित कार्यक्रम लिखा था जो उचित क्रम में मूल्यों को आउटपुट करने के लिए इस तेज पूर्णांक विभाजन कोड का more_itertools.powersetउपयोग करता था , लेकिन फिर मुझे पता चला और अधिकांश उपयोगों के लिए शायद यह ठीक है कि इस तरह के फ़ंक्शन का उपयोग करें:

from more_itertools import powerset
from numpy import ediff1d

def ps_sorter(tup):
    l = len(tup)
    d = ediff1d(tup).tolist()
    return l, d

ps = powerset([1,2,3,4])

ps = sorted(ps, key=ps_sorter)

for x in ps:
    print(x)

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

मैं कुछ और अधिक शामिल कोड जो Powerset अच्छी तरह से प्रिंट होगा लिखा था (सुंदर कार्यों मैं यहाँ शामिल नहीं किया है मुद्रण के लिए रेपो देखें: print_partitions, print_partitions_by_length, और pprint_tuple)।

यह सब बहुत आसान है, लेकिन फिर भी यह उपयोगी हो सकता है यदि आप कुछ कोड चाहते हैं जो आपको सीधे अधिकार के विभिन्न स्तरों तक पहुँचने में मदद करेगा:

from itertools import permutations as permute
from numpy import cumsum

# http://jeromekelleher.net/generating-integer-partitions.html
# via
# /programming/10035752/elegant-python-code-for-integer-partitioning#comment25080713_10036764

def asc_int_partitions(n):
    a = [0 for i in range(n + 1)]
    k = 1
    y = n - 1
    while k != 0:
        x = a[k - 1] + 1
        k -= 1
        while 2 * x <= y:
            a[k] = x
            y -= x
            k += 1
        l = k + 1
        while x <= y:
            a[k] = x
            a[l] = y
            yield tuple(a[:k + 2])
            x += 1
            y -= 1
        a[k] = x + y
        y = x + y - 1
        yield tuple(a[:k + 1])

# https://stackoverflow.com/a/6285330/2668831
def uniquely_permute(iterable, enforce_sort=False, r=None):
    previous = tuple()
    if enforce_sort: # potential waste of effort (default: False)
        iterable = sorted(iterable)
    for p in permute(iterable, r):
        if p > previous:
            previous = p
            yield p

def sum_min(p):
    return sum(p), min(p)

def partitions_by_length(max_n, sorting=True, permuting=False):
    partition_dict = {0: ()}
    for n in range(1,max_n+1):
        partition_dict.setdefault(n, [])
        partitions = list(asc_int_partitions(n))
        for p in partitions:
            if permuting:
                perms = uniquely_permute(p)
                for perm in perms:
                    partition_dict.get(len(p)).append(perm)
            else:
                partition_dict.get(len(p)).append(p)
    if not sorting:
        return partition_dict
    for k in partition_dict:
        partition_dict.update({k: sorted(partition_dict.get(k), key=sum_min)})
    return partition_dict

def print_partitions_by_length(max_n, sorting=True, permuting=True):
    partition_dict = partitions_by_length(max_n, sorting=sorting, permuting=permuting)
    for k in partition_dict:
        if k == 0:
            print(tuple(partition_dict.get(k)), end="")
        for p in partition_dict.get(k):
            print(pprint_tuple(p), end=" ")
        print()
    return

def generate_powerset(items, subset_handler=tuple, verbose=False):
    """
    Generate the powerset of an iterable `items`.

    Handling of the elements of the iterable is by whichever function is passed as
    `subset_handler`, which must be able to handle the `None` value for the
    empty set. The function `string_handler` will join the elements of the subset
    with the empty string (useful when `items` is an iterable of `str` variables).
    """
    ps = {0: [subset_handler()]}
    n = len(items)
    p_dict = partitions_by_length(n-1, sorting=True, permuting=True)
    for p_len, parts in p_dict.items():
        ps.setdefault(p_len, [])
        if p_len == 0:
            # singletons
            for offset in range(n):
                subset = subset_handler([items[offset]])
                if verbose:
                    if offset > 0:
                        print(end=" ")
                    if offset == n - 1:
                        print(subset, end="\n")
                    else:
                        print(subset, end=",")
                ps.get(p_len).append(subset)
        for pcount, partition in enumerate(parts):
            distance = sum(partition)
            indices = (cumsum(partition)).tolist()
            for offset in range(n - distance):
                subset = subset_handler([items[offset]] + [items[offset:][i] for i in indices])
                if verbose:
                    if offset > 0:
                        print(end=" ")
                    if offset == n - distance - 1:
                        print(subset, end="\n")
                    else:
                        print(subset, end=",")
                ps.get(p_len).append(subset)
        if verbose and p_len < n-1:
            print()
    return ps

एक उदाहरण के रूप में, मैंने एक सीएलआई डेमो प्रोग्राम लिखा जो कमांड लाइन तर्क के रूप में एक स्ट्रिंग लेता है:

python string_powerset.py abcdef

a, b, c, d, e, f

ab, bc, cd, de, ef
ac, bd, ce, df
ad, be, cf
ae, bf
af

abc, bcd, cde, def
abd, bce, cdf
acd, bde, cef
abe, bcf
ade, bef
ace, bdf
abf
aef
acf
adf

abcd, bcde, cdef
abce, bcdf
abde, bcef
acde, bdef
abcf
abef
adef
abdf
acdf
acef

abcde, bcdef
abcdf
abcef
abdef
acdef

abcdef

0

यदि आप चाहते हैं कि आप किसी भी विशिष्ट लम्बाई की उप-पट्टियाँ बना सकते हैं:

from itertools import combinations
someSet = {0, 1, 2, 3}
([x for i in range(len(someSet)+1) for x in combinations(someSet,i)])

आम तौर पर मनमाने ढंग से लंबाई वाले सबसेट के लिए आप रेंज आर्गन को संशोधित कर सकते हैं। आउटपुट है

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


0
def powerset(some_set):
    res = [(a,b) for a in some_set for b in some_set]
    return res

6
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह कोड क्यों और / या इस बारे में अतिरिक्त संदर्भ प्रदान करता है कि यह प्रश्न इसके दीर्घकालिक मूल्य में सुधार करता है। इसे बेहतर बनाने के लिए अपने उत्तर को कैसे पढ़ें और संपादित करें पर विचार करें
ब्लफफस

2
क्या @blurfus हमेशा एक अच्छा अभ्यास है, लेकिन विशेष रूप से महत्वपूर्ण है जब आप एक दशक पुराने प्रश्न का उत्तर 28 अन्य उत्तरों के साथ दे रहे हैं। यह स्वीकार किए गए उत्तर पर सुधार क्यों है? यह जवाब क्या योगदान देता है कि अन्य उत्तर प्रदान नहीं करते हैं?
जेरेमी कैनी

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