Заказанная пара из повторяющегося списка - PullRequest
0 голосов
/ 03 мая 2018

У меня есть список, который может иметь или не иметь повторяющиеся элементы, я хочу создать упорядоченные пары, так что в элементе x повторяется x, x является допустимой парой в остальном все x, y, когда x

пока я нашел очень непитонный способ сделать это

def foo(a):
    n = list()
    for x in range(len(a)):
        for y in range(x+1,len(a)):
            if a[x] < a[y]:
                n.append([a[x],a[y]])
            else:
                n.append([a[y],a[x]])
    o = list()
    for p in n:
        if not (p in o):
            o.append(p)
    return o

print(foo([1,3,5,-1]))
# [[1, 3], [1, 5], [-1, 1], [3, 5], [-1, 3], [-1, 5]]

print(foo([1,1,5,5]))
# [[1, 1], [1, 5], [5, 5]]

print(foo([1,1,1,1]))
# [[1, 1]]

я знаю, что могу использовать списочное понимание, но решение, которое я попробовал, либо пропускает тип x, x, когда присутствуют повторы, либо и фантом x, x, который не должен присутствовать

a = [1,3,5,-1]
o = [[x,y] for x in a for y in a if x<=y]
print(o)
[[1, 1], [1, 3], [1, 5], [3, 3], [3, 5], [5, 5], [-1, 1], [-1, 3], [-1, 5], [-1, -1]]

что будет подходящим питоническим решением для удобочитаемости.

Кроме того, что будет наиболее эффективным по времени (память не является ограничением), если питонное решение не самое эффективное

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Если вы довольны использованием itertools, вы можете использовать itertools.combinations:

from itertools import combinations

a = [1, 3, 5, -1]
o = sorted(set(combinations(sorted(a), 2)))

>>> [(-1, 1), (-1, 3), (-1, 5), (1, 3), (1, 5), (3, 5)]

a = [1, 1, 5, 5]
o = sorted(set(combinations(sorted(a), 2)))

>>> [(1, 1), (1, 5), (5, 5)]

Внутренний вызов sorted гарантирует, что каждая пара будет заказана, что, как я понимаю, было вашим намерением. Внешний вызов sorted гарантирует, что пары упорядочены. Если в этом нет необходимости, вы можете заменить это sorted на list.

0 голосов
/ 07 мая 2018

Если вы не довольны itertools, вы можете использовать понимание списка.

>>> xs = [1,3,5,-1]

Если вы пронесете xs со всеми своими подсписками, начиная с индекса 1, 2, ..., len (xs) -1, вы получите все комбинации:

>>> [list(zip(xs,xs[n:])) for n in range(1,len(xs))]
[[(1, 3), (3, 5), (5, -1)], [(1, 5), (3, -1)], [(1, -1)]]

(Обратите внимание, что я обернул здесь zip в list для лучшего вывода.) Теперь вы должны сгладить список кортежей. Это просто понимание списка с каждым кортежем каждого списка кортежей, полученного с помощью zip:

>>> [t for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys]
[(1, 3), (3, 5), (5, -1), (1, 5), (3, -1), (1, -1)]

Вы хотите отсортированные кортежи: это tuple(sorted(t)), потому что отсортированный возвращает список. Поместите все в set, чтобы удалить дубликаты.

>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(-1, 1), (1, 3), (-1, 3), (1, 5), (-1, 5), (3, 5)}

(Вы также можете, как это сделал silkworm, отсортировать список перед выводом кортежей.) Другие тестовые случаи:

>>> xs = [1,1,1,1]
>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(1, 1)}
>>> xs = [1,1,5,5]
>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(1, 5), (5, 5), (1, 1)}

Совет: вы должны использовать itertools ...

0 голосов
/ 03 мая 2018

Вы пытались использовать itertools.combination ()

Примерно так

import itertools
iterable = [1,1,5,5]
r=2
comb = sorted(set(itertools.combinations(sorted(iterable), r)))
for el in comb:
  print(el)
...