Combinar elementos de listas si alguna condición.

¿Cómo combino los elementos de una lista si se cumple alguna condición?

He visto publicaciones sobre la combinación de elementos de una lista, pero no con alguna condición.

Digamos que tengo una lista que contiene listas de palabras:

words = [ ['this','that!','riff','raff'], ['hip','hop!','flip!','flop'], ['humpty','dumpty!','professor!','grumpy!'] ] 

¿Cómo combino solo aquellos elementos que contienen un ! ?

Por ejemplo, la salida se vería así:

 [['this', 'that!', 'riff', 'raff'], ['hip', 'hop!, flip!', 'flop'], # 1,2 are now combined ['humpty', 'dumpty!, professor!, grumpy!']] # 1,2,3 are now combined 

Intenté esto:

 for word in words: word = ', '.join(i for i in word if re.search('!',str(i))) print word 

pero consiguió

 that! hop!, flip! dumpty!, professor!, grumpy! 

Gracias.

Utilice itertools.groupby :

 >>> from itertools import groupby >>> out = [] >>> for lst in words: d = [] for k, g in groupby(lst, lambda x: '!' in x): if k: d.append(', '.join(g)) else: d.extend(g) out.append(d) ... >>> out [['this', 'that!', 'riff', 'raff'], ['hip', 'hop!, flip!', 'flop'], ['humpty', 'dumpty!, professor!, grumpy!']] 

Aquí está mi solución:

 words = [ ['this','that!','riff','raff'], ['hip','hop!','flip!','flop'], ['humpty','dumpty!','professor!','grumpy!'] ] output = [] for wl in words: out_wl = [] bang_wl = [] for w in wl: if '!' in w: bang_wl.append(w) else: if bang_wl: out_wl.append(','.join(bang_wl)) bang_wl = [] out_wl.append(w) if bang_wl: out_wl.append(','.join(bang_wl)) output.append(out_wl) print output 

Salida:

 [['this', 'that!', 'riff', 'raff'], ['hip', 'hop!,flip!', 'flop'], ['humpty', 'dumpty!,professor!,grumpy!']] 

bang_wl acumula palabras con ! hasta que golpea una palabra que no contiene una ! . En este punto, join las palabras en bang_wl y se agrega a la lista de output_wl .

 result = [] for sub_lst in words: result.append([]) temp = "" for ele in sub_lst: if not temp and not "!" in ele: result[-1].append(ele) elif temp and not "!" in ele: result[-1].append(temp) result[-1].append(ele) temp = "" else: temp += "," + ele if temp else ele if temp: result[-1].append(temp) [['this', 'that!', 'riff', 'raff'], ['humpty', 'dumpty!,professor!,grumpy!'], ['hip', 'hop!,flip!', 'flop']] 

Si quieres todas las palabras con un ! para unirse, incluidas las palabras separadas por palabras que no contienen una ! es decir, ['humpty', 'dumpty!', 'professor!', 'grumpy!',"foo","bar!"] se convertiría en ['humpty', 'foo', 'dumpty!,professor!,grumpy!,bar!'] :

 result = [] for sub_l in words: result.append([]) temp = "" for word in sub_l: if "!" in word: temp += "," + word if temp else word else: result[-1].append(word) result[-1].append(temp) 

Algunos horarios muestran que @vikramls es el más eficiente y la solución de itertools es la menos eficiente .:

 In [31]: %%timeit ....: result = [] ....: for sub_lst in words: ....: result.append([]) ....: temp = "" ....: for ele in sub_lst: ....: if not temp and not "!" in ele: ....: result[-1].append(ele) ....: elif temp and not "!" in ele: ....: result[-1].append(temp) ....: result[-1].append(ele) ....: temp = "" ....: else: ....: temp += "," + ele if temp else ele ....: if temp: ....: result[-1].append(temp) ....: 100000 loops, best of 3: 16 µs per loop In [32]: %%timeit output = [] for wl in words: out_wl = [] bang_wl = [] for w in wl: if '!' in w: bang_wl.append(w) else: if bang_wl: out_wl.append(','.join(bang_wl)) bang_wl = [] out_wl.append(w) if bang_wl: out_wl.append(','.join(bang_wl)) output.append(out_wl) ....: 100000 loops, best of 3: 15.2 µs per loop In [33]: %%timeit out = [] >>> for lst in words: d = [] for k, g in groupby(lst, lambda x: '!' in x): if k: d.append(', '.join(g)) else: d.extend(g) out.append(d) ....: 10000 loops, best of 3: 48.1 µs per loop 

Si solo quieres que las palabras terminen con un ! :

 In [34]: %%timeit result = [] for sub_lst in words: result.append([]) temp = "" for ele in sub_lst: if not temp and not ele[-1] == "!": result[-1].append(ele) elif temp and not ele[-1] == "!": result[-1].append(temp) result[-1].append(ele) temp = "" else: temp += "," + ele if temp else ele if temp: result[-1].append(temp) ....: 100000 loops, best of 3: 17 µs per loop