2016-12-16 11 views
0

У меня есть список, если элементы/кортежи, которые содержат наборы, как это:Сформировать последовательность строк, основываясь на шнурке выборки из строки фрагментов

a_list = [(a, {x}), (b, {y}), (c, {y,z}), (d, {y,z}), (e, {x,y}), (f, {x,y,z})] 

И образец образец:

pattern = {x,y} 

Учитывая количество рисунков, я хотел бы сгенерировать последовательность элементов из списка a_list, который больше всего подходит для шаблона. Образец должен выполняться со второй частью кортежа, набором.

Пример:

Результат с draws = 2 может быть:

result = [(a, {x}), (b, {y})] 
# x, y 

или

result = [(e, {x,y}), (a, {x})] 
# x, y 

или

result = [(e, {x,y}), (b, {y})] 
# x, y 

В обоих случаях выполнить шаблон {х, у} в течение 2 ничьих ,

Результат с draws = 1 может быть только:

result = (e, {x,y}) 
# x, y 

, так как есть только одна ничья, чтобы выполнить шаблон и единственный элемент е соответствует шаблону полностью.

Результат с draws = 7 может быть:

result = [(a, {x}), (b, {y}), (e, {x,y}), (f, {x,y,z}), (c, {y,z})] 
# x, y, x, y, x, y, y 

Может ли такая функция будет выполнена, и если, как?

Благодарим за помощь!

сдобы

+0

Что вы подразумеваете под «накладными расходами» и «ничьей»? является 'draw' * ожидаемым * число {x, y} должно быть в конечных множествах? – TuanDT

+0

«draw» - это количество раз, когда элемент из a_list берется и оценивается по шаблону. – Raggamuffin

+0

Я удалил накладные расходы, это просто усложняло мысль. С накладными расходами я имею в виду, когда я беру 7 элементов из списка, и у шаблона есть 2 предмета, в идеале шаблон подходит 3 раза, а последний ничья подходит только для части рисунка. эта часть i вызывает накладные расходы. – Raggamuffin

ответ

0

Если то, что я понял из вашего вопроса и ваши комментарии правильно, то ниже функция должна дать вам правильный выход/печать и должна быть равна тому, что вы ожидали в вашем вопросе.

Вот мое решение

from itertools import groupby 
from random import randint 

a_list = [('a', {'x'}), ('b', {'y'}), ('c', {'y','z'}), ('d', {'y','z'}), ('e', {'x','y'}), ('f', {'x','y','z'})] 

pattern = {'x', 'y'} 


def seq_gen(a = [], pattern = set, draws = 0): 
    single, multi = [], [] 

    for i in a: 
     if len(i[1]) == 1: 
      single.append(i) 
     else: 
      multi.append(i) 

    final = [j for j in single if list(pattern)[0] in j[1] or list(pattern)[1] in j[1]] 
    final += [j for j in multi if pattern == j[1]] 
    # Debug 
    #print(final) 

    if draws == 1: 
     for i in final: 
      if len(i[1]) == 2: 
       # for better use, return a list not a tuple 
       return "draw(1) => {0}".format([i]) 

    if draws > len(final): 
     k, f = list(), tuple() 
     for _, v in groupby(a, lambda x: x[1]): 
      # Debug 
      #print(list(v)) 
      k += list(v)[0] 

     return "draw({0}) => {1}".format(draws, [tuple(k[x:x+2]) for x in range(0,len(k), 2)]) 

    if draws == len(final): 
     return "draw({0}) => {1}".format(draws, final) 

    else: 
     aa = [] 
     while len(aa) != 2: 
      element = final[randint(0, len(final) -1)] 
      if element not in aa: 
       aa.append(element) 
     return "draw({0}) => {1}".format(draws, aa) 

for i in range(1,8): 
    print(seq_gen(a_list, pattern, i)) 

Выход:

draw(1) => [('e', {'x', 'y'})] 
draw(2) => [('e', {'x', 'y'}), ('a', {'x'})] 
draw(3) => [('a', {'x'}), ('b', {'y'}), ('e', {'x', 'y'})] 
draw(4) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})] 
draw(5) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})] 
draw(6) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})] 
draw(7) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})] 

PS: Не стесняйтесь вернуть ваши обратные связи. Если что-то не так, я попытаюсь исправить его новыми запросами.

+1

вместо того, чтобы преобразовать его в список, использовать операцию набора, такую ​​как пересечение, также изменить значение по умолчанию из '{}' to 'set()' или еще лучше 'frozenset()' потому что '{}' производить словарь – Copperfield

+0

Да, вы правы. Но я пытался создать тот же результат, что и OP. Также это не полное решение. Я жду обратной связи с OP, потому что у меня не было запросов от 2 до 7 и как с ними бороться. –