Liste içeriğini kombinatorik olarak parçalara ayırmak

Herkese Merhaba,

Bir fonksiyon yazmak istiyorum.
Fonksiyonun görevi, liste içeriğini (kombinasyon hesabına göre) bölümlere ayırmak olacak.

örnek liste şu olsun;
listem = [1,2,3,4,5]


def bolumle(liste):
    ...
    ...
    ...

bolumle(listem)

olmasını istediğim Çıktı:

ikili = [[1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]]

üclü = [[1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5], [3,4,5]]

dörtlü = [[1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]

liste içeriği değiştikçe (arttıkça, ya da azaldıkça) sonuç beşli, altılı,…vb değişecek.

Kombinasyon hesabına göre;

  • [ kombinasyon(5,2) = 5! / ((5-2)!*2!) = 10 ] 10 adet İKİLİ liste elemanı oluşturulmalı. Aşağıda 2 elemanlı liste barındıran 10 elemanlı ana liste görülüyor.
    ikili = [[1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]]

  • [ kombinasyon(5,3) = 5! / ((5-3)!*3!) = 10 ] 10 adet ÜÇLÜ liste elemanı oluşturulmalı. Aşağıda 3 elemanlı liste barındıran 10 elemanlı ana liste görülüyor.
    üclü = [[1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5], [3,4,5]]

  • [ kombinasyon(5,4) = 5! / ((5-4)!*4!) = 5 ] 5 adet DÖRTLÜ liste elemanı oluşturulmalı. Aşağıda 4 elemanlı liste barındıran 5 elemanlı ana liste görülüyor.
    dörtlü = [[1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]

Bu işlemi bir tek fonksiyon ile yapmak mümkün mü? Yoksa her bir grup için (ikili, üçlü, dörtlü,…vb) ayrı birer fonksiyon mu yazmak gerekir?

Merhabalar,

itertools modülündeki combinations fonksiyonunu kulanabilirsiniz. Bu fonksiyon 2 parametre alıyor: ilki kombinasyonlar oluşturmak istediğiniz iterable diğeri de bu kombinasyonların “kaçlı” olduğu. Ve “combinations object” döndürüyor, siz bunu uygun veri tiplerine dönüştürebilirsiniz (liste, demet gibi). Dönüştürdüğünüzde (listedeki veya demetteki) her bir eleman demet tipinde olacaktır.

Örnek:

>>> from itertools import combinations
>>> liste = [1, 2, 3, 4, 5]
>>> ikili = list(combinations(liste, 2))
>>> ikili
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
>>> # elemanların her biri demet tipinde, listeye çevirebiliriz sizin örneğinizde olduğu üzere:
... ikili = [[*komb] for komb in ikili]
>>> ikili
[[1, 2], [1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], [3, 4], [3, 5], [4, 5]]

Dolayısıyla şöyle genelleyen bir fonksiyon yazabiliriz:

from itertools import combinations
def bolumle(liste, n):
    """Verilen listenin n'li kombinasyonlarını listeler halinde oluşturur 
    ve hepsini bir liste dahilinde döndürür"""
    n_li = list(combinations(liste, n))
    return [[*n_li_komb] for n_li_komb in n_li]

Eğer L uzunluğundaki listenin 2’den (L-1)'e kadar olan kombinasyonlarını döndürmek istiyorsanız, fonksiyonu, içinde for döndürecek şekilde düzenlemeniz yeterli olur herhalde.

3 Beğeni

Çok teşekkür ederim Then_Shiffman.
Aradığım cevap buydu.

Söylediğiniz gibi döngüyü de kurdum;

from itertools import combinations

def bolumle(liste, n):
    n_li = list(combinations(liste, n))
    print(n, "'li kombinasyon işlemi ile", len(n_li), "adet liste elemanı üretilmektedir.")
    return [[*n_li_komb] for n_li_komb in n_li]

listem = [1, 2, 3, 4, 5]

for i in range(2, len(listem)):
    print(i, "'li kombinasyon sonucu: ", bolumle(listem,i))

Çıktı:

2 'li kombinasyon işlemi ile 10 adet liste elemanı üretilmektedir.
2 'li kombinasyon sonucu:  [[1, 2], [1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], [3, 4], [3, 5], [4, 5]]
3 'li kombinasyon işlemi ile 10 adet liste elemanı üretilmektedir.
3 'li kombinasyon sonucu:  [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
4 'li kombinasyon işlemi ile 5 adet liste elemanı üretilmektedir.
4 'li kombinasyon sonucu:  [[1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]]

**itertools** modülü ve **combinations** fonksiyonu hakkında detay arayanlar için, aşağıda python belgeler sayfalarına ait bağlantıları paylaşıyorum.

Python2 için: https://docs.python.org/2/library/itertools.html#itertools.combinations
Python3 için: https://docs.python.org/3.7/library/itertools.html?highlight=itertools#itertools.combinations