दो सूचियों के बीच संयोजन?


187

यह एक समय हो गया है और मुझे एक एल्गोरिथ्म के चारों ओर अपना सिर लपेटने में परेशानी हो रही है जिसे मैं बनाने की कोशिश कर रहा हूं। मूल रूप से, मेरी दो सूचियाँ हैं और दोनों सूचियों के सभी संयोजन प्राप्त करना चाहते हैं।

मैं इसे सही नहीं समझा रहा हूँ तो यहाँ एक उदाहरण है।

name = 'a', 'b'
number = 1, 2

इस मामले में आउटपुट होगा:

1.  A1 B2
2.  B1 A2

मुश्किल हिस्सा यह है कि मेरे पास "संख्या" चर में आइटम की तुलना में "नाम" चर में अधिक आइटम हो सकते हैं (संख्या हमेशा नाम चर की तुलना में कम या बराबर होगी)।

मैं उलझन में हूं कि सभी संयोजनों को कैसे किया जाए (लूप के लिए नेस्टेड?) और इससे भी अधिक उलझन में तर्क है कि आइटम को नाम चर में इस घटना में स्थानांतरित करने के लिए कि संख्या सूची में वे नाम से अधिक आइटम हैं।

मैं सबसे अच्छा प्रोग्रामर नहीं हूं, लेकिन मुझे लगता है कि मैं इसे एक शॉट दे सकता हूं अगर कोई मुझे इसे हासिल करने के लिए तर्क / algoriythm को स्पष्ट करने में मदद कर सकता है। तो मैं सिर्फ छोरों के लिए नेस्टेड पर अटक गया हूं।

अपडेट करें:

यहाँ 3 चर और 2 संख्याओं के साथ आउटपुट दिया गया है:

name = 'a', 'b', 'c'
number = 1, 2

उत्पादन:

1.  A1 B2
2.  B1 A2
3.  A1 C2
4.  C1 A2
5.  B1 C2
6.  C1 B2


1
@ dm03514 मैंने देखा कि, और कुछ इसी तरह के लक्ष्यों के लिए itertools का उपयोग करने के उदाहरण मिलते हैं, लेकिन मैं अजगर में प्रोटोटाइप कर रहा हूं, लेकिन किसी अन्य भाषा में अंतिम कोड लिखूंगा, इसलिए मैं ऐसे किसी भी उपकरण का उपयोग नहीं करना चाहता जो एल्सवे का लाभ नहीं उठा रहा है।
user1735075

1
क्या आप के लिए पूछ रहे हैं वास्तव में मतलब नहीं है। यदि पहली सूची में A, B, C और दूसरे में 1,2 शामिल हैं, तो आप किस परिणाम की उम्मीद करेंगे? यह तब किया जा सकता है यदि आपने जो उदाहरण दिया है उसमें एक अक्षर के 4 अलग-अलग परिणाम और प्रत्येक (A1, A2, B1, B2) या यदि दोनों सूचियों का आकार समान होना चाहिए।
इंटर '17

1
मैं अंतरजाल से सहमत हूं। कृपया परिणाम को गैर-बराबर आकार के मामले में निर्दिष्ट करें, अन्यथा सामान्य समाधान प्रदान करना संभव नहीं है।
बकुरीउ

हाय सब लोग, मैंने 3 नामों और 2 नंबरों के साथ आउटपुट दिखाने के लिए उत्तर को अपडेट किया..मुझे लगा कि मैंने इसे अच्छी तरह से समझाया है, यह सुनिश्चित नहीं है कि डाउनवोट क्यों है।
user1735075

जवाबों:


93

नोट : यह उत्तर ऊपर पूछे गए विशिष्ट प्रश्न के लिए है। यदि आप Google से यहां आए हैं और केवल पायथन में कार्टेसियन उत्पाद प्राप्त करने का तरीका ढूंढ रहे हैं, itertools.productया एक साधारण सूची की समझ हो सकती है, जिसे आप ढूंढ रहे हैं - अन्य उत्तर देखें।


मान लीजिए len(list1) >= len(list2)। फिर जो आप चाहते हैं वह यह है कि लंबाई के सभी क्रमपरिवर्तन len(list2)से लें list1और उन्हें सूची 2 से आइटम के साथ मिलाएं। अजगर में:

import itertools
list1=['a','b','c']
list2=[1,2]

[list(zip(x,list2)) for x in itertools.permutations(list1,len(list2))]

रिटर्न

[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]

1
परिणाम ठीक वही है जो मैं चाहता हूं, लेकिन क्या इसे कैसे करना है इसके पीछे तर्क को साझा करना संभव है? यदि मैं अपने कोड को C या Java में परिवर्तित करता हूं, तो मेरे पास ज़िप या इटर्स्टूल तक पहुंच नहीं होगी (हालांकि वे जीवन को बहुत आसान बनाते हैं)
user1735075


1
@ user1735075: क्या आप जानते हैं कि अजगर खुला स्रोत है? तो आप बस स्रोतों को डाउनलोड कर सकते हैं और देख सकते हैं कि वे क्या करते हैं। +1 श्री स्टेक को इंगित करने के लिए कि प्रलेखन का वास्तव में एक नमूना कार्यान्वयन है जो उपयोग नहीं करता है zipऔर समान है।
बकुरीउ

2
मैं सचमुच अपने उदाहरण के साथ काम करने के लिए इसे प्राप्त नहीं कर सकता ... सब मुझे मिलता है ज़िप वस्तु की एक सूची है ..: |
m1nkeh 10

1
@logic प्रदान करता है कि स्वीकृत समाधान क्या होना चाहिए।
बर्नहार्ड वैगनर

499

उपयोग करने का सबसे सरल तरीका है itertools.product:

a = ["foo", "melon"]
b = [True, False]
c = list(itertools.product(a, b))
>> [("foo", True), ("foo", False), ("melon", True), ("melon", False)]

10
ओपी कार्टेशियन उत्पाद के लिए नहीं पूछ रहा था, और यह उत्तर (साथ ही अधिकांश अन्य) प्रश्न में निर्दिष्ट अपेक्षित परिणाम नहीं देता है।
इंटरज्यू जूल

17
@interjay आप बहुत सही हैं लेकिन बहुत से लोगों को यह उत्तर सही लगता है तो मैं केवल यह मान सकता हूं कि प्रश्न का शीर्षक संदर्भ का अभाव है।
xpy

3
@xpy सब कुछ समझाने के लिए शीर्षक बहुत छोटा है। इसलिए आपको वास्तविक प्रश्न पढ़ने की आवश्यकता है।
इंटरज्यू जूल

10
ओपी को अनुमति चाहिए थी, लेकिन Google इस जवाब के लिए किसी को भी (जैसे मेरे) संयोजन की तलाश में भेजता है - यह देखकर खुशी हुई कि इसे 8 गुना वोट मिले हैं!
जोश फ्रीडलैंडर

159

ऊपर दिए गए सबसे सरल से आसान हो सकता है:

>>> a = ["foo", "bar"]
>>> b = [1, 2, 3]
>>> [(x,y) for x in a for y in b]  # for a list
[('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)]
>>> ((x,y) for x in a for y in b)  # for a generator if you worry about memory or time complexity.
<generator object <genexpr> at 0x1048de850>

बिना किसी आयात के


सबसे अच्छा उपाय! धन्यवाद! अन्य समाधान या तो सीधे गलत हैं या केवल विशिष्ट मामलों जैसे> b आदि में काम करते हैं
फिलिप श्वार्ज़

3
सबसे Pythonic समाधान! (और अनावश्यक आयात से बचा जाता है)
डल्कर

6
समय की जटिलता हे (n ^ 2)
दीपक शर्मा

2
समाधान देता है !! बेयर बेसिक्स हमेशा सबसे अच्छा तरीका है
सब्यसाची

22

मैं केवल अद्वितीय संयोजनों के साथ खुद से गुणा की गई सूची की तलाश में था, जो इस फ़ंक्शन के रूप में प्रदान की जाती है।

import itertools
itertools.combinations(list, n_times)

यहाँ पर पायथन डॉक्स के itertools एक अंश के रूप में, जो आपको आपकी तलाश में मदद कर सकता है।

Combinatoric generators:

Iterator                                 | Results
-----------------------------------------+----------------------------------------
product(p, q, ... [repeat=1])            | cartesian product, equivalent to a 
                                         |   nested for-loop
-----------------------------------------+----------------------------------------
permutations(p[, r])                     | r-length tuples, all possible 
                                         |   orderings, no repeated elements
-----------------------------------------+----------------------------------------
combinations(p, r)                       | r-length tuples, in sorted order, no 
                                         |   repeated elements
-----------------------------------------+----------------------------------------
combinations_with_replacement(p, r)      | r-length tuples, in sorted order, 
                                         | with repeated elements
-----------------------------------------+----------------------------------------
product('ABCD', repeat=2)                | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)                  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)                  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD

11

आप एक पंक्ति सूची समझने की कोशिश करना चाह सकते हैं:

>>> [name+number for name in 'ab' for number in '12']
['a1', 'a2', 'b1', 'b2']
>>> [name+number for name in 'abc' for number in '12']
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']

10

बड़ी संख्या में सूचियों के लिए सभी संयोजनों का पता लगाने का सबसे अच्छा तरीका है:

import itertools
from pprint import pprint

inputdata = [
    ['a', 'b', 'c'],
    ['d'],
    ['e', 'f'],
]
result = list(itertools.product(*inputdata))
pprint(result)

परिणाम होगा:

[('a', 'd', 'e'),
 ('a', 'd', 'f'),
 ('b', 'd', 'e'),
 ('b', 'd', 'f'),
 ('c', 'd', 'e'),
 ('c', 'd', 'f')]

धन्यवाद, शानदार जवाब!
toinbis

10

या छोटे सूचियों के लिए KISS जवाब:

[(i, j) for i in list1 for j in list2]

नहीं के रूप में itertools के रूप में प्रदर्शन कर रहे हैं, लेकिन आप अजगर का उपयोग कर रहे हैं तो प्रदर्शन पहले से ही अपने शीर्ष चिंता का विषय नहीं है ...

मुझे अन्य सभी उत्तर भी पसंद हैं!


8

इंटरजेन से उत्तर के लिए एक छोटा सुधार, परिणाम को एक समतल सूची के रूप में बनाने के लिए।

>>> list3 = [zip(x,list2) for x in itertools.permutations(list1,len(list2))]
>>> import itertools
>>> chain = itertools.chain(*list3)
>>> list4 = list(chain)
[('a', 1), ('b', 2), ('a', 1), ('c', 2), ('b', 1), ('a', 2), ('b', 1), ('c', 2), ('c', 1), ('a', 2), ('c', 1), ('b', 2)]

इस लिंक से संदर्भ


4

Itertools के बिना

[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]

4

"दो सूचियों को दिए गए प्रश्न" का उत्तर देते हुए, प्रत्येक सूची में से एक आइटम के जोड़े के सभी संभावित क्रमों को ढूंढें "और बुनियादी पायथन कार्यक्षमता (यानी, इटर्टूल के बिना) का उपयोग करना और, इसलिए, अन्य प्रोग्रामिंग भाषाओं के लिए प्रतिकृति बनाना आसान है:

def rec(a, b, ll, size):
    ret = []
    for i,e in enumerate(a):
        for j,f in enumerate(b):
            l = [e+f]
            new_l = rec(a[i+1:], b[:j]+b[j+1:], ll, size)
            if not new_l:
                ret.append(l)
            for k in new_l:
                l_k = l + k
                ret.append(l_k)
                if len(l_k) == size:
                    ll.append(l_k)
    return ret

a = ['a','b','c']
b = ['1','2']
ll = []
rec(a,b,ll, min(len(a),len(b)))
print(ll)

रिटर्न

[['a1', 'b2'], ['a1', 'c2'], ['a2', 'b1'], ['a2', 'c1'], ['b1', 'c2'], ['b2', 'c1']]

2

इसके लिए बेहतर उत्तर केवल विशिष्ट सूचियों की लंबी सूची के लिए काम करते हैं जो प्रदान की जाती हैं।

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

from itertools import combinations, permutations
list1 = ['1', '2']
list2 = ['A', 'B', 'C']

num_elements = min(len(list1), len(list2))
list1_combs = list(combinations(list1, num_elements))
list2_perms = list(permutations(list2, num_elements))
result = [
  tuple(zip(perm, comb))
  for comb in list1_combs
  for perm in list2_perms
]

for idx, ((l11, l12), (l21, l22)) in enumerate(result):
  print(f'{idx}: {l11}{l12} {l21}{l22}')

यह आउटपुट:

0: A1 B2
1: A1 C2
2: B1 A2
3: B1 C2
4: C1 A2
5: C1 B2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.