2016-12-16 40 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 

兩種情況履行模式{X,Y}在2平局之內。

draws = 1一個結果只能是:

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

由於只有一個平局履行模式,僅項目E模式完全匹配。

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

'overhead'和'draw'是什麼意思?是'draw'的*期望的數量{x,y}必須在最終集合中? – TuanDT

+0

「draw」是a_list中的一個元素被獲取並根據該模式進行評估的次數。 – Raggamuffin

+0

我刪除了開銷,這使思想複雜化。開銷我的意思是,當我從列表中選取7個項目,並且模式有2個項目時,理想情況下該模式適合3次,最後一個繪製只適合該模式的一部分。那部分我打電話開銷。 – 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

而不是將其轉換爲列表,使用set操作(如交集),也可將默認值從'{}到'set()'或更好的'frozenset()',因爲'{}'產生一個字典 – Copperfield

+0

是的,你是對的。但我試圖產生像OP想要的一樣的輸出。這也不是完整的解決方案。我在等待OP反饋,因爲我沒有得到2到7之間的所有查詢以及如何處理它們。 –