একটি সিরিজের তালিকার কারটিশিয়ান পণ্য পান?


317

আমি কীভাবে একটি গ্রুপের তালিকা থেকে কার্তেসিয়ান পণ্য (প্রতিটি সম্ভাব্য মানের সংমিশ্রণ) পেতে পারি?

ইনপুট:

somelists = [
   [1, 2, 3],
   ['a', 'b'],
   [4, 5]
]

পছন্দসই আউটপুট:

[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]

24
সচেতন থাকুন যে 'প্রতিটি সম্ভাব্য সংমিশ্রণ' 'কার্টেসিয়ান পণ্য' এর মতো নয়, যেহেতু কার্টেসিয়ান পণ্যগুলিতে নকলকে অনুমতি দেওয়া হয়েছে allowed
ট্রিপটিচ

7
কারটিশিয়ান পণ্যের কোনও নকল সংস্করণ আছে?
কেজেডাব্লু

16
@ কেজেডাব্লু হ্যাঁ,set(cartesian product)
NoBugs

5
কার্টেসিয়ান পণ্যতে কোনও সদৃশ থাকা উচিত নয়, যদি না ইনপুট তালিকাগুলিতে ডুপ্লিকেট থাকে। আপনি যদি কার্টেসিয়ান পণ্যটিতে কোনও সদৃশ চান না, set(inputlist)আপনার সমস্ত ইনপুট তালিকা ব্যবহার করুন। ফলাফল নয়।
ক্যামিলবি

@ ট্রাইপাইচ কী? কার্টেসিয়ান পণ্যের মানক সংজ্ঞাটি একটি সেট। কেন এত লোক উপবিষ্ট হয়?
পাসকালআইভ

উত্তর:


378

itertools.product

পাইথন ২.6 থেকে পাওয়া যায়।

import itertools

somelists = [
   [1, 2, 3],
   ['a', 'b'],
   [4, 5]
]
for element in itertools.product(*somelists):
    print(element)

যা একই,

for element in itertools.product([1, 2, 3], ['a', 'b'], [4, 5]):
    print(element)

22
কেবল '*' চরিত্রটি যুক্ত করতে চেয়েছিলেন যদি আপনি ওপি দ্বারা সরবরাহিত ভেরিয়েবল সোললিস্ট ব্যবহার করেন।
ব্রায়ান বাক

1
@ জাসকা: ফলাফলটিতে উপাদান product()তৈরি nitems_in_a_list ** nlistsকরে ( reduce(mul, map(len, somelists)))। বিশ্বাস করার কোনও কারণ নেই যে একটি একক উপাদান উত্পাদন করা হয় না O(nlists)(amorised) অর্থাত্, সময় জটিলতা সরল নেস্টেড- forলুপগুলি যেমন সমান, যেমন প্রশ্নের প্রশ্নে ইনপুট :,nlists=3 ফলাফলের মোট উপাদানগুলির সংখ্যা: 3*2*2এবং প্রতিটি উপাদান nlistsআইটেম আছে ( 3এই ক্ষেত্রে)।
jfs

2
*সোল্লিস্টদের আগে ব্যবহার কী ? এটার কাজ কি?
বিনীত কুমার দোশি

6
@ ভিনিটকুমারদোশি: এখানে এটি ফাংশন কলটিতে একাধিক যুক্তিতে একটি তালিকা আনপ্যাক করতে ব্যবহৃত হয়। এখানে আরও পড়ুন: স্ট্যাকওভারফ্লো
মোবার্গ

4
দ্রষ্টব্য: প্রতিটি তালিকায় কমপক্ষে একটি আইটেম থাকলে কেবল এটি কাজ করে
ইগো

84
import itertools
>>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
...         print i
...
(1, 'a', 4)
(1, 'a', 5)
(1, 'b', 4)
(1, 'b', 5)
(2, 'a', 4)
(2, 'a', 5)
(2, 'b', 4)
(2, 'b', 5)
(3, 'a', 4)
(3, 'a', 5)
(3, 'b', 4)
(3, 'b', 5)
>>>

38

পাইথন 2.5 এবং এর বেশি বয়সীদের জন্য:

>>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]

এখানে একটি পুনরাবৃত্ত সংস্করণ product()(কেবল একটি চিত্র):

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])

উদাহরণ:

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]

পুনরাবৃত্ত সংস্করণটি কিছু কাজ করে যদি argsতা পুনরুক্তি হয় work
jfs

20

সঙ্গে itertools.product :

import itertools
result = list(itertools.product(*somelists))

6
*সোল্লিস্টদের আগে ব্যবহার কী ?
বিনীত কুমার দোশি

@ ভিনিটকুমারদোশি "প্রোডাক্ট (সোললিস্টস)" হ'ল সাবলেটলিস্টগুলির মধ্যে এমন একটি কার্টেসিয়ান পণ্য যা পাইথন প্রথমে একটি উপাদান হিসাবে "[[1, 2, 3]" পায় এবং তারপরে পরবর্তী কমমানের পরে অন্য উপাদান পায় এবং এটি লাইন ব্রেক হয় তাই প্রথম পণ্য পদটি ([1, 2, 3],), দ্বিতীয় ([4, 5],) এর সমান এবং "" ([[1, 2, 3],)), ([4, 5],), ( [6, 7],)] " । আপনি যদি টিউপসগুলির অভ্যন্তরের উপাদানগুলির মধ্যে কার্টেসিয়ান পণ্য পেতে চান তবে আপনাকে অ্যাসিরিস্টকের সাথে পাইথনকে টিউপল কাঠামোর বিষয়ে বলতে হবে। অভিধানের জন্য, আপনি ** ব্যবহার করুন। আরও এখানে
hhh

19

আমি তালিকা বোধগম্যতা ব্যবহার করব:

somelists = [
   [1, 2, 3],
   ['a', 'b'],
   [4, 5]
]

cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]

1
আমি তালিকা বোধগম্যতা ব্যবহার করে এই সমাধানটি সত্যিই পছন্দ করি। আমি জানি না কেন আরও বেশি উত্সাহ দেওয়া হয় না, এটি এত সহজ।
llekn

20
@ লেলেকন কারণ কোডগুলি তালিকার সংখ্যার সাথে স্থির বলে মনে হচ্ছে
বং রিকিমারু

11

এখানে একটি পুনরাবৃত্ত জেনারেটর, যা কোনও অস্থায়ী তালিকা সংরক্ষণ করে না

def product(ar_list):
    if not ar_list:
        yield ()
    else:
        for a in ar_list[0]:
            for prod in product(ar_list[1:]):
                yield (a,)+prod

print list(product([[1,2],[3,4],[5,6]]))

আউটপুট:

[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]

1
যদিও তারা স্ট্যাকের মধ্যে সংরক্ষণ করা হয়।
কোয়ান্টিন প্রদেট

@ কুইন্টিনপ্রেড আপনি কী বোঝাতে চাইছেন যে কোনও জেনারেটর def f(): while True: yield 1এর মধ্য দিয়ে যাবার সাথে সাথে তার স্ট্যাকের আকার বাড়িয়ে রাখবে?
অনুরাগ ইউনিয়াল

@ কন্টিনপ্রেড হ্যাঁ, তবে এই ক্ষেত্রে কেবল সর্বোচ্চ গভীরতার জন্য কেবল স্ট্যাকের প্রয়োজন, পুরো তালিকা নয়, তাই এই ক্ষেত্রে 3 এর স্ট্যাক
অনুরাগ ইউনিিয়াল

সত্য, দুঃখিত। একটি মানদণ্ড আকর্ষণীয় হতে পারে। :)
কোয়ান্টিন প্রদেশ

11

পাইথন ২.6 এবং তার উপরে আপনি 'itertools.pr Prodct` ব্যবহার করতে পারেন ` পাইথনের পুরানো সংস্করণগুলিতে আপনি নথি থেকে নিম্নের (প্রায় - ডকুমেন্টেশন দেখুন) সমতুল্য কোডটি কমপক্ষে একটি প্রাথমিক পয়েন্ট হিসাবে ব্যবহার করতে পারেন :

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

উভয়ের ফলাফলই একটি পুনরাবৃত্তিকারী, সুতরাং যদি আপনার প্রকৃতপক্ষে প্রক্রিয়াজাতকরণের জন্য কোনও তালিকা প্রয়োজন হয় তবে ব্যবহার করুন list(result)


ডকুমেন্টেশন অনুসারে, প্রকৃত itertools. উত্পাদক বাস্তবায়ন মধ্যবর্তী ফলাফল তৈরি করে না, যা ব্যয়বহুল হতে পারে। মাঝারি আকারের তালিকার জন্য এই কৌশলটি ব্যবহার করা খুব দ্রুত হাত থেকে নামতে পারে।
ট্রিপটিচ

4
আমি কেবল ওপিটিকে ডকুমেন্টেশনের দিকে নির্দেশ করতে পারি, এটি তার জন্য পড়তে পারি না।

1
ডকুমেন্টেশন থেকে কোডটি বোঝানো হয়েছে যে পণ্য ফাংশনটি কী করে তা বোঝায়, পাইথনের আগের সংস্করণগুলির জন্য কাজ হিসাবে নয়।
ট্রিপটিচ

9

যদিও ইতিমধ্যে অনেকগুলি উত্তর রয়েছে তবে আমি আমার কিছু চিন্তাভাবনা ভাগ করে নিতে চাই:

Iterative পদ্ধতির

def cartesian_iterative(pools):
  result = [[]]
  for pool in pools:
    result = [x+[y] for x in result for y in pool]
  return result

পুনরাবৃত্তি পদ্ধতির

def cartesian_recursive(pools):
  if len(pools) > 2:
    pools[0] = product(pools[0], pools[1])
    del pools[1]
    return cartesian_recursive(pools)
  else:
    pools[0] = product(pools[0], pools[1])
    del pools[1]
    return pools
def product(x, y):
  return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]

ল্যাম্বদা অ্যাপ্রোচ

def cartesian_reduct(pools):
  return reduce(lambda x,y: product(x,y) , pools)

"আইট্রেটিভ অ্যাপ্রোচ" এ, ফলাফলকে ফলাফল হিসাবে কেন ঘোষণা করা হয় = [[]] আমি জানি যে এটি তালিকা_ও_ তালিকাগুলি তবে সাধারণভাবে আমরা তালিকা_ও_ তালিকাকে ব্যবহার করি []] না [[]]
শচীন এস

পাইথোনিক সমাধানগুলির ক্ষেত্রে আমি একদম নতুন আপনি বা কোনও পথচারী দয়া করে পৃথক লুপগুলিতে "পুনরাবৃত্তি পদ্ধতির" তালিকাটি উপলব্ধিটি লিখবেন?
জনি বয়

খুব চতুর সমাধান! এর পিছনে অন্তর্দৃষ্টি খুব শীতল ছিল!
কৃষ

4

পুনরাবৃত্তি পদ্ধতির:

def rec_cart(start, array, partial, results):
  if len(partial) == len(array):
    results.append(partial)
    return 

  for element in array[start]:
    rec_cart(start+1, array, partial+[element], results)

rec_res = []
some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]  
rec_cart(0, some_lists, [], rec_res)
print(rec_res)

Iterative পদ্ধতির:

def itr_cart(array):
  results = [[]]
  for i in range(len(array)):
    temp = []
    for res in results:
      for element in array[i]:
        temp.append(res+[element])
    results = temp

  return results

some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]  
itr_res = itr_cart(some_lists)
print(itr_res)

3

ভেরিয়াদিক স্বাদে উপরের পুনরাবৃত্ত জেনারেটর সমাধানটিতে একটি সামান্য পরিবর্তন:

def product_args(*args):
    if args:
        for a in args[0]:
            for prod in product_args(*args[1:]) if args[1:] else ((),):
                yield (a,) + prod

এবং অবশ্যই একটি মোড়ক এটি সমাধান হিসাবে ঠিক একই কাজ করে তোলে:

def product2(ar_list):
    """
    >>> list(product(()))
    [()]
    >>> list(product2(()))
    []
    """
    return product_args(*ar_list)

সঙ্গে এক বাণিজ্য বন্ধ এটা চেক যদি পুনরাবৃত্তির প্রতিটি বাইরের লুপ উপর বিরতি উচিত, এবং: এক লাভ : খালি কল উপর কোন ফলন যেমনproduct(()) , যা আমি অনুমান শব্দার্থগতভাবে আরো সঠিক হবে (doctest দেখুন)।

তালিকা অনুধাবন সম্পর্কে: গাণিতিক সংজ্ঞাটি একটি স্বেচ্ছাসেবী যুক্তিতে প্রযোজ্য, যখন তালিকা বোধগম্যতা কেবল তাদের একটি জ্ঞাত সংখ্যার সাথেই ডিল করতে পারে।


2

ইতিমধ্যে যা বলা হয়েছে তাতে কিছুটা যুক্ত করার জন্য: আপনি যদি সিম্পি ব্যবহার করেন তবে আপনি স্ট্রিংয়ের পরিবর্তে চিহ্নগুলি ব্যবহার করতে পারেন যা এগুলি গাণিতিকভাবে দরকারী makes

import itertools
import sympy

x, y = sympy.symbols('x y')

somelist = [[x,y], [1,2,3], [4,5]]
somelist2 = [[1,2], [1,2,3], [4,5]]

for element in itertools.product(*somelist):
  print element

আমাদের সম্পর্কে sympy



0

স্টোনহেঞ্জ পদ্ধতির:

def giveAllLists(a, t):
    if (t + 1 == len(a)):
        x = []
        for i in a[t]:
            p = [i]
            x.append(p)
        return x
    x = []

    out = giveAllLists(a, t + 1)
    for i in a[t]:

        for j in range(len(out)):
            p = [i]
            for oz in out[j]:
                p.append(oz)
            x.append(p)
    return x

xx= [[1,2,3],[22,34,'se'],['k']]
print(giveAllLists(xx, 0))

আউটপুট:

[[1, 22, 'k'], [1, 34, 'k'], [1, 'se', 'k'], [2, 22, 'k'], [2, 34, 'k'], [2, 'se', 'k'], [3, 22, 'k'], [3, 34, 'k'], [3, 'se', 'k']]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.