Jak podzielić listę na pary na wszystkie możliwe sposoby

87

Mam listę (powiedzmy 6 elementów dla uproszczenia)

L = [0, 1, 2, 3, 4, 5]

i chcę podzielić go na pary na WSZYSTKIE możliwe sposoby. Pokazuję kilka konfiguracji:

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

i tak dalej. Tutaj (a, b) = (b, a)i kolejność par nie jest ważna tj

[(0, 1), (2, 3), (4, 5)] = [(0, 1), (4, 5), (2, 3)]

Łączna liczba takich konfiguracji jest 1*3*5*...*(N-1)gdzie Njest długość mojej liście.

Jak napisać generator w Pythonie, który da mi wszystkie możliwe konfiguracje dla dowolnego N?

Adam
źródło
2
Możesz spojrzeć na ten standardowy moduł, itertoolsjeśli jeszcze tego nie zrobiłeś. Funkcje tam powinny być w stanie pomóc w rozwiązaniu tego problemu (prawdopodobnie funkcje permutations, combinationslub product).
dappawit
Jeśli kolejność nie jest ważna, prawdopodobnie powinieneś użyć zestawów lub zamrażarek.
asmeurer
Mówiąc językiem kombinatoryki, chcesz wygenerować wszystkie idealne dopasowania na danym zestawie (w pełnym wykresie).
Valentas,

Odpowiedzi:

106

Spójrz na itertools.combinations.

matt@stanley:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import itertools
>>> list(itertools.combinations(range(6), 2))
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
Matt Joiner
źródło
47
To nie jest to, o co chodzi w pytaniu ... ale tak się składa, że ​​to jest to, czego szukałem :)
gatoatigrado
5
Dlaczego jest to najbardziej przychylna odpowiedź? Nie wydaje się odpowiadać na pytanie.
Halbort
11
Odpowiada na pytanie większości ludzi, którzy odwiedzają tę witrynę.
Kontrolowane radiowo
2
@Halbort Odpowiada jednak tytułowi, więc pomaga wielu ludziom. Poza tym jest to z pewnością główny problem OP. Oto kombinacje iterowalnego elementu , teraz podziel go, jak chcesz.
OJFord,
1
@OJFord Nie wydaje mi się, żeby to odpowiadało tytułowi: Myślę, że „podzielenie” listy oznacza, że ​​otrzymujemy rozłączne podzbiory oryginału. Twierdziłbym, że ta odpowiedź brzmi: „Jak wygenerować wszystkie możliwe pary z listy”. Przypuszczam jednak, że nadal może być prawdą, że jest to odpowiedź, której szuka większość ludzi.
Zack
40

Nie sądzę, aby w standardowej bibliotece była jakaś funkcja, która robi dokładnie to, czego potrzebujesz. Samo użycie itertools.combinationsmoże dać ci listę wszystkich możliwych pojedynczych par, ale tak naprawdę nie rozwiązuje problemu wszystkich prawidłowych kombinacji par.

Możesz to łatwo rozwiązać za pomocą:

import itertools
def all_pairs(lst):
    for p in itertools.permutations(lst):
        i = iter(p)
        yield zip(i,i)

Ale w ten sposób otrzymasz duplikaty, ponieważ traktuje (a, b) i (b, a) jako różne, a także podaje wszystkie uporządkowania par. W końcu doszedłem do wniosku, że łatwiej jest to zakodować od zera niż próbować filtrować wyniki, więc oto poprawna funkcja.

def all_pairs(lst):
    if len(lst) < 2:
        yield []
        return
    if len(lst) % 2 == 1:
        # Handle odd length list
        for i in range(len(lst)):
            for result in all_pairs(lst[:i] + lst[i+1:]):
                yield result
    else:
        a = lst[0]
        for i in range(1,len(lst)):
            pair = (a,lst[i])
            for rest in all_pairs(lst[1:i]+lst[i+1:]):
                yield [pair] + rest

Jest rekurencyjny, więc wystąpią problemy ze stosem z długą listą, ale poza tym robi to, czego potrzebujesz.

>>> for x in all_pairs ([0,1,2,3,4,5]):
    drukuj x

[(0, 1), (2, 3), (4, 5)]
[(0, 1), (2, 4), (3, 5)]
[(0, 1), (2, 5), (3, 4)]
[(0, 2), (1, 3), (4, 5)]
[(0, 2), (1, 4), (3, 5)]
[(0, 2), (1, 5), (3, 4)]
[(0, 3), (1, 2), (4, 5)]
[(0, 3), (1, 4), (2, 5)]
[(0, 3), (1, 5), (2, 4)]
[(0, 4), (1, 2), (3, 5)]
[(0, 4), (1, 3), (2, 5)]
[(0, 4), (1, 5), (2, 3)]
[(0, 5), (1, 2), (3, 4)]
[(0, 5), (1, 3), (2, 4)]
[(0, 5), (1, 4), (2, 3)]
shang
źródło
16
Domyślnie Python ma stos zwrotny o głębokości 1000 wywołań. Powtarzasz się na parach cyfr, więc nie powinno to stanowić problemu, dopóki lista nie będzie zawierać prawie 2000 pozycji. Przy zaledwie 50 przedmiotach otrzymujesz więcej niż 5 * 10 ^ 31 kombinacji; napotkasz miliard lat obliczeń na długo zanim głębokość stosu stanie się problemem.
Hugh Bothwell,
4
To klasyczny sposób pisania tego.
hughdbrown
Wygląda na to, że jest problem z tą odpowiedzią (działa Python 2.7.11). Pierwszy wiersz wyjścia, gdy uruchomiony dokładnie tych samych zwrotów kod: [(0, 1), (2, 3), 4].
Alceu Costa
2
Przepraszam, jestem pewien, że odpowiedź została napisana z najlepszymi intencjami, ale jest niepoprawna dla wszystkich list wejściowych o nieparzystej długości
Moritz Walter.
2
@MoritzWalter Jakie były oczekiwane dane wyjściowe dla list wejściowych o nieparzystej długości? Dla mnie to pytanie nie ma nawet sensu, jeśli listy mają nieparzystą długość, ponieważ nie można ich podzielić na pary.
Zack
15

Co powiesz na to:

items = ["me", "you", "him"]
[(items[i],items[j]) for i in range(len(items)) for j in range(i+1, len(items))]

[('me', 'you'), ('me', 'him'), ('you', 'him')]

lub

items = [1, 2, 3, 5, 6]
[(items[i],items[j]) for i in range(len(items)) for j in range(i+1, len(items))]

[(1, 2), (1, 3), (1, 5), (1, 6), (2, 3), (2, 5), (2, 6), (3, 5), (3, 6), (5, 6)]
lefterav
źródło
1
cóż, nie grupuje zestawów par
Janus Troelsen
10

Koncepcyjnie podobny do odpowiedzi @ shang, ale nie zakłada, że ​​grupy mają rozmiar 2:

import itertools

def generate_groups(lst, n):
    if not lst:
        yield []
    else:
        for group in (((lst[0],) + xs) for xs in itertools.combinations(lst[1:], n-1)):
            for groups in generate_groups([x for x in lst if x not in group], n):
                yield [group] + groups

pprint(list(generate_groups([0, 1, 2, 3, 4, 5], 2)))

To daje:

[[(0, 1), (2, 3), (4, 5)],
 [(0, 1), (2, 4), (3, 5)],
 [(0, 1), (2, 5), (3, 4)],
 [(0, 2), (1, 3), (4, 5)],
 [(0, 2), (1, 4), (3, 5)],
 [(0, 2), (1, 5), (3, 4)],
 [(0, 3), (1, 2), (4, 5)],
 [(0, 3), (1, 4), (2, 5)],
 [(0, 3), (1, 5), (2, 4)],
 [(0, 4), (1, 2), (3, 5)],
 [(0, 4), (1, 3), (2, 5)],
 [(0, 4), (1, 5), (2, 3)],
 [(0, 5), (1, 2), (3, 4)],
 [(0, 5), (1, 3), (2, 4)],
 [(0, 5), (1, 4), (2, 3)]]
tokland
źródło
5

Mój szef prawdopodobnie nie będzie zadowolony, że spędziłem trochę czasu nad tym zabawnym problemem, ale oto fajne rozwiązanie, które nie wymaga rekursji i używa itertools.product. Jest to wyjaśnione w dokumentacji :). Wyniki wydają się OK, ale nie testowałem tego za bardzo.

import itertools


def all_pairs(lst):
    """Generate all sets of unique pairs from a list `lst`.

    This is equivalent to all _partitions_ of `lst` (considered as an indexed
    set) which have 2 elements in each partition.

    Recall how we compute the total number of such partitions. Starting with
    a list

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

    one takes off the first element, and chooses its pair [from any of the
    remaining 5].  For example, we might choose our first pair to be (1, 4).
    Then, we take off the next element, 2, and choose which element it is
    paired to (say, 3). So, there are 5 * 3 * 1 = 15 such partitions.

    That sounds like a lot of nested loops (i.e. recursion), because 1 could
    pick 2, in which case our next element is 3. But, if one abstracts "what
    the next element is", and instead just thinks of what index it is in the
    remaining list, our choices are static and can be aided by the
    itertools.product() function.
    """
    N = len(lst)
    choice_indices = itertools.product(*[
        xrange(k) for k in reversed(xrange(1, N, 2)) ])

    for choice in choice_indices:
        # calculate the list corresponding to the choices
        tmp = lst[:]
        result = []
        for index in choice:
            result.append( (tmp.pop(0), tmp.pop(index)) )
        yield result

Twoje zdrowie!

gatoatigrado
źródło
bardziej precyzyjna nazwa powinna być all_pairingsi xrangepowinna zostać zastąpiona rangew Pythonie 3.
Valentas
Implementacja jest czysta, ale nie działa dla list z nieparzystą liczbą elementów.
Mattia Rossi
4

Wypróbuj następującą rekurencyjną funkcję generatora:

def pairs_gen(L):
    if len(L) == 2:
        yield [(L[0], L[1])]
    else:
        first = L.pop(0)
        for i, e in enumerate(L):
            second = L.pop(i)
            for list_of_pairs in pairs_gen(L):
                list_of_pairs.insert(0, (first, second))
                yield list_of_pairs
            L.insert(i, second)
        L.insert(0, first)

Przykładowe użycie:

>>> for pairs in pairs_gen([0, 1, 2, 3, 4, 5]):
...     print pairs
...
[(0, 1), (2, 3), (4, 5)]
[(0, 1), (2, 4), (3, 5)]
[(0, 1), (2, 5), (3, 4)]
[(0, 2), (1, 3), (4, 5)]
[(0, 2), (1, 4), (3, 5)]
[(0, 2), (1, 5), (3, 4)]
[(0, 3), (1, 2), (4, 5)]
[(0, 3), (1, 4), (2, 5)]
[(0, 3), (1, 5), (2, 4)]
[(0, 4), (1, 2), (3, 5)]
[(0, 4), (1, 3), (2, 5)]
[(0, 4), (1, 5), (2, 3)]
[(0, 5), (1, 2), (3, 4)]
[(0, 5), (1, 3), (2, 4)]
[(0, 5), (1, 4), (2, 3)]
Adeel Zafar Soomro
źródło
3

Nierekurencyjna funkcja znajdująca wszystkie możliwe pary, w których kolejność nie ma znaczenia, tj. (A, b) = (b, a)

def combinantorial(lst):
    count = 0
    index = 1
    pairs = []
    for element1 in lst:
        for element2 in lst[index:]:
            pairs.append((element1, element2))
        index += 1

    return pairs

Ponieważ nie jest cykliczny, nie będziesz mieć problemów z pamięcią w przypadku długich list.

Przykład użycia:

my_list = [1, 2, 3, 4, 5]
print(combinantorial(my_list))
>>>
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
melqkiades
źródło
1
To jest to samo, co itertools.combinations
Tmdean
3

Zrobiłem mały zestaw testów dla wszystkich zgodnych rozwiązań. Musiałem trochę zmienić funkcje, aby działały w Pythonie 3. Co ciekawe, najszybsza funkcja w PyPy to w niektórych przypadkach najwolniejsza funkcja w Pythonie 2/3.

import itertools 
import time
from collections import OrderedDict

def tokland_org(lst, n):
    if not lst:
        yield []
    else:
        for group in (((lst[0],) + xs) for xs in itertools.combinations(lst[1:], n-1)):
            for groups in tokland_org([x for x in lst if x not in group], n):
                yield [group] + groups

tokland = lambda x: tokland_org(x, 2)

def gatoatigrado(lst):
    N = len(lst)
    choice_indices = itertools.product(*[
        range(k) for k in reversed(range(1, N, 2)) ])

    for choice in choice_indices:
        # calculate the list corresponding to the choices
        tmp = list(lst)
        result = []
        for index in choice:
            result.append( (tmp.pop(0), tmp.pop(index)) )
        yield result

def shang(X):
    lst = list(X)
    if len(lst) < 2:
        yield lst
        return
    a = lst[0]
    for i in range(1,len(lst)):
        pair = (a,lst[i])
        for rest in shang(lst[1:i]+lst[i+1:]):
            yield [pair] + rest

def smichr(X):
    lst = list(X)
    if not lst:
        yield [tuple()]
    elif len(lst) == 1:
        yield [tuple(lst)]
    elif len(lst) == 2:
        yield [tuple(lst)]
    else:
        if len(lst) % 2:
            for i in (None, True):
                if i not in lst:
                    lst = lst + [i]
                    PAD = i
                    break
            else:
                while chr(i) in lst:
                    i += 1
                PAD = chr(i)
                lst = lst + [PAD]
        else:
            PAD = False
        a = lst[0]
        for i in range(1, len(lst)):
            pair = (a, lst[i])
            for rest in smichr(lst[1:i] + lst[i+1:]):
                rv = [pair] + rest
                if PAD is not False:
                    for i, t in enumerate(rv):
                        if PAD in t:
                            rv[i] = (t[0],)
                            break
                yield rv

def adeel_zafar(X):
    L = list(X)
    if len(L) == 2:
        yield [(L[0], L[1])]
    else:
        first = L.pop(0)
        for i, e in enumerate(L):
            second = L.pop(i)
            for list_of_pairs in adeel_zafar(L):
                list_of_pairs.insert(0, (first, second))
                yield list_of_pairs
            L.insert(i, second)
        L.insert(0, first)

if __name__ =="__main__":
    import timeit
    import pprint

    candidates = dict(tokland=tokland, gatoatigrado=gatoatigrado, shang=shang, smichr=smichr, adeel_zafar=adeel_zafar)

    for i in range(1,7):
        results = [ frozenset([frozenset(x) for x in candidate(range(i*2))]) for candidate in candidates.values() ]
        assert len(frozenset(results)) == 1

    print("Times for getting all permutations of sets of unordered pairs consisting of two draws from a 6-element deck until it is empty")
    times = dict([(k, timeit.timeit('list({0}(range(6)))'.format(k), setup="from __main__ import {0}".format(k), number=10000)) for k in candidates.keys()])
    pprint.pprint([(k, "{0:.3g}".format(v)) for k,v in OrderedDict(sorted(times.items(), key=lambda t: t[1])).items()])

    print("Times for getting the first 2000 permutations of sets of unordered pairs consisting of two draws from a 52-element deck until it is empty")
    times = dict([(k, timeit.timeit('list(islice({0}(range(52)), 800))'.format(k), setup="from itertools import islice; from __main__ import {0}".format(k), number=100)) for k in candidates.keys()])
    pprint.pprint([(k, "{0:.3g}".format(v)) for k,v in OrderedDict(sorted(times.items(), key=lambda t: t[1])).items()])

    """
    print("The 10000th permutations of the previous series:")
    gens = dict([(k,v(range(52))) for k,v in candidates.items()])
    tenthousands = dict([(k, list(itertools.islice(permutations, 10000))[-1]) for k,permutations in gens.items()])
    for pair in tenthousands.items():
        print(pair[0])
        print(pair[1])
    """

Wydaje się, że wszystkie generują dokładnie tę samą kolejność, więc zestawy nie są konieczne, ale w ten sposób jest to przyszłościowe. Trochę poeksperymentowałem z konwersją do Pythona 3, nie zawsze jest jasne, gdzie zbudować listę, ale wypróbowałem kilka alternatyw i wybrałem najszybszą.

Oto wyniki testów porównawczych:

% echo "pypy"; pypy all_pairs.py; echo "python2"; python all_pairs.py; echo "python3"; python3 all_pairs.py
pypy
Times for getting all permutations of sets of unordered pairs consisting of two draws from a 6-element deck until it is empty
[('gatoatigrado', '0.0626'),
 ('adeel_zafar', '0.125'),
 ('smichr', '0.149'),
 ('shang', '0.2'),
 ('tokland', '0.27')]
Times for getting the first 2000 permutations of sets of unordered pairs consisting of two draws from a 52-element deck until it is empty
[('gatoatigrado', '0.29'),
 ('adeel_zafar', '0.411'),
 ('smichr', '0.464'),
 ('shang', '0.493'),
 ('tokland', '0.553')]
python2
Times for getting all permutations of sets of unordered pairs consisting of two draws from a 6-element deck until it is empty
[('gatoatigrado', '0.344'),
 ('adeel_zafar', '0.374'),
 ('smichr', '0.396'),
 ('shang', '0.495'),
 ('tokland', '0.675')]
Times for getting the first 2000 permutations of sets of unordered pairs consisting of two draws from a 52-element deck until it is empty
[('adeel_zafar', '0.773'),
 ('shang', '0.823'),
 ('smichr', '0.841'),
 ('tokland', '0.948'),
 ('gatoatigrado', '1.38')]
python3
Times for getting all permutations of sets of unordered pairs consisting of two draws from a 6-element deck until it is empty
[('gatoatigrado', '0.385'),
 ('adeel_zafar', '0.419'),
 ('smichr', '0.433'),
 ('shang', '0.562'),
 ('tokland', '0.837')]
Times for getting the first 2000 permutations of sets of unordered pairs consisting of two draws from a 52-element deck until it is empty
[('smichr', '0.783'),
 ('shang', '0.81'),
 ('adeel_zafar', '0.835'),
 ('tokland', '0.969'),
 ('gatoatigrado', '1.3')]
% pypy --version
Python 2.7.12 (5.6.0+dfsg-0~ppa2~ubuntu16.04, Nov 11 2016, 16:31:26)
[PyPy 5.6.0 with GCC 5.4.0 20160609]
% python3 --version
Python 3.5.2

Więc mówię, idź z rozwiązaniem Gatoatigrado.

Janus Troelsen
źródło
2
def f(l):
    if l == []:
        yield []
        return
    ll = l[1:]
    for j in range(len(ll)):
        for end in f(ll[:j] + ll[j+1:]):
            yield [(l[0], ll[j])] + end

Stosowanie:

for x in f([0,1,2,3,4,5]):
    print x

>>> 
[(0, 1), (2, 3), (4, 5)]
[(0, 1), (2, 4), (3, 5)]
[(0, 1), (2, 5), (3, 4)]
[(0, 2), (1, 3), (4, 5)]
[(0, 2), (1, 4), (3, 5)]
[(0, 2), (1, 5), (3, 4)]
[(0, 3), (1, 2), (4, 5)]
[(0, 3), (1, 4), (2, 5)]
[(0, 3), (1, 5), (2, 4)]
[(0, 4), (1, 2), (3, 5)]
[(0, 4), (1, 3), (2, 5)]
[(0, 4), (1, 5), (2, 3)]
[(0, 5), (1, 2), (3, 4)]
[(0, 5), (1, 3), (2, 4)]
[(0, 5), (1, 4), (2, 3)]
Jules Olléon
źródło
Ups, nie widziałem odpowiedzi shanga, co powoduje to samo ... czy mam usunąć tę?
Jules Olléon,
Nie ma potrzeby usuwania, ale użycie przez shang prawdziwych nazw zmiennych jest lepsze.
gatoatigrado
1

Ten kod działa, gdy długość listy nie jest wielokrotnością 2; wykorzystuje hack, aby to działało. Być może istnieją lepsze sposoby, aby to zrobić ... Zapewnia również, że pary są zawsze w krotce i że działa to niezależnie od tego, czy dane wejściowe są listą, czy krotką.

def all_pairs(lst):
    """Return all combinations of pairs of items of ``lst`` where order
    within the pair and order of pairs does not matter.

    Examples
    ========

    >>> for i in range(6):
    ...  list(all_pairs(range(i)))
    ...
    [[()]]
    [[(0,)]]
    [[(0, 1)]]
    [[(0, 1), (2,)], [(0, 2), (1,)], [(0,), (1, 2)]]
    [[(0, 1), (2, 3)], [(0, 2), (1, 3)], [(0, 3), (1, 2)]]
    [[(0, 1), (2, 3), (4,)], [(0, 1), (2, 4), (3,)], [(0, 1), (2,), (3, 4)], [(0, 2)
    , (1, 3), (4,)], [(0, 2), (1, 4), (3,)], [(0, 2), (1,), (3, 4)], [(0, 3), (1, 2)
    , (4,)], [(0, 3), (1, 4), (2,)], [(0, 3), (1,), (2, 4)], [(0, 4), (1, 2), (3,)],
     [(0, 4), (1, 3), (2,)], [(0, 4), (1,), (2, 3)], [(0,), (1, 2), (3, 4)], [(0,),
    (1, 3), (2, 4)], [(0,), (1, 4), (2, 3)]]

    Note that when the list has an odd number of items, one of the
    pairs will be a singleton.

    References
    ==========

    http://stackoverflow.com/questions/5360220/
    how-to-split-a-list-into-pairs-in-all-possible-ways

    """
    if not lst:
        yield [tuple()]
    elif len(lst) == 1:
        yield [tuple(lst)]
    elif len(lst) == 2:
        yield [tuple(lst)]
    else:
        if len(lst) % 2:
            for i in (None, True):
                if i not in lst:
                    lst = list(lst) + [i]
                    PAD = i
                    break
            else:
                while chr(i) in lst:
                    i += 1
                PAD = chr(i)
                lst = list(lst) + [PAD]
        else:
            PAD = False
        a = lst[0]
        for i in range(1, len(lst)):
            pair = (a, lst[i])
            for rest in all_pairs(lst[1:i] + lst[i+1:]):
                rv = [pair] + rest
                if PAD is not False:
                    for i, t in enumerate(rv):
                        if PAD in t:
                            rv[i] = (t[0],)
                            break
                yield rv
smichr
źródło
1

Mam nadzieję, że to pomoże:

L = [0, 1, 2, 3, 4, 5]

[(i, j) dla i w L dla j w L]

wynik:

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

Kiran Puligorla
źródło
(0, 0)nie jest parą z listy. (0, 1)i (1, 0)są równoważne
Caveman
0
L = [1, 1, 2, 3, 4]
answer = []
for i in range(len(L)):
    for j in range(i+1, len(L)):
        if (L[i],L[j]) not in answer:
            answer.append((L[i],L[j]))

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

Mam nadzieję że to pomoże

inspectorG4dget
źródło
-2

Nie jest to najbardziej wydajny ani najszybszy, ale prawdopodobnie najłatwiejszy. Ostatnia linia to prosty sposób na deduplikację listy w Pythonie. W tym przypadku na wyjściu są pary takie jak (0,1) i (1,0). Nie jestem pewien, czy rozważasz te duplikaty, czy nie.

l = [0, 1, 2, 3, 4, 5]
pairs = []
for x in l:
    for y in l:
        pairs.append((x,y))
pairs = list(set(pairs))
print(pairs)

Wynik:

[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)]
FrankFcknCastle
źródło
Zduplikowane pary na liście (0, 1)to ta sama para co (1, 0). Zobacz pytanie
Caveman