comparar elementos de dos listas

A = [a1, a2, a3...] #a1<a2<a3... B = [b1, b2...] #b1<b2<b3... 

A y B son inconexos. No conozco la cantidad de elementos y su valor en A / B por adelantado. Quiero comparar el valor de los elementos en la lista y eliminar elementos iff:

 delete a[i+1] if there is no b[j] such that a[i]<b[j]<a[i+1] delete b[i+1] if there is no a[j] such that b[i]<a[j]<b[i+1] 

Al final, quiero separar la lista, no una combinación de A y B.

Por ejemplo, si A[0] < B[0] , A = [1, 10, 40], B = [15, 30]. Compara A[1] y B[0] primero. Elimine 10 porque ningún elemento en B está entre 1 y 15. Luego elimine 15 porque ya no existe ningún elemento entre 15 y 30. El resultado debería ser: si intenta ordenar los elementos de las nuevas 2 listas, debe ser A[0]<B[0]<A[1]<B[1]<...

Si A[0] > B[0] , viceversa.

 a = [1, 10, 40] b = [15, 30] srcs = [a, b] dsts = [[], []] prev_which = -1 while all(srcs): which = int(srcs[0][0] > srcs[1][0]) elem = srcs[which].pop(0) if prev_which != which: dsts[which].append(elem) prev_which = which for src, dst in zip(srcs,dsts): if src: dst.append(src.pop(0)) a, b = dsts 

devoluciones:

 a = [1, 40] b = [15] 

y para

 a = [3, 4, 6, 7, 8, 9] b = [1, 2, 5, 10] 

devuelve [3, 6] y [1, 5, 10] .

EDITAR : otra posibilidad:

 import itertools as it import operator as op a = [3, 4, 6, 7, 8, 9] b = [1, 2, 5, 10] srcs = [a, b] dsts = [[], []] for which, elems in it.groupby(sorted((x, i) for i in (0,1) for x in srcs[i]), key=op.itemgetter(1)): dsts[which].append(next(elems)[0]) a, b = dsts 

Se me ocurrió esto antes de editar. Pero parece que la salida no es lo que esperas. De todos modos, podría ayudarte a encontrar el camino correcto:

 a = range(0, 30, 3) b = range(0, 20, 2) a.sort() b.sort() A = [a[i+1] for i in range(len(a)-1) if any(a[i] 

Esto es "literalmente" lo que expresaste, pero el result aquí no es lo que esperas. Intentaré mejorar esto.

Entonces, si estoy leyendo correctamente, la salida deseada de su ejemplo es [1,40] y [15], ¿sí?

Si es así, lo siguiente obtendría el resultado correcto, pero estoy seguro de que hay una forma más estricta de hacerlo.

 a = [1, 10, 40] b = [15, 30] c = sorted([[e_a,'a'] for e_a in a] + [[e_b,'b'] for e_b in b]) indices = [] for i in range(len(c)-1): if c[i][1] == c[i+1][1]: indices.append(i+1) for e in sorted(indices, reverse=True): del c[e] a,b = [e[0] for e in c if e[1]=='a'],[e[0] for e in c if e[1]=='b'] 

Primero: fusione las listas y clasifíquelas, a la vez que realiza un seguimiento de la lista de la que proceden.

Segundo: luego elimine todas las instancias en las que el siguiente elemento de la lista combinada sea de la misma lista de origen.

Tercero – actualizando a y b.

Sabía que usar el módulo bisect podría ser una buena solución:

 >>> def sort_relative(L1, L2): # Switch if needed if L1[0] > L2[0]: L1, L2 = L2, L1 i = 0 while i + 1 < max(len(L1), len(L2)): try: # We know that L1[i] < L2[i] # Get indexes where L2[i] and L2[i + 1] should be inserted i11 = bisect.bisect_left(L1, L2[i]) i12 = bisect.bisect_left(L1, L2[i + 1]) # This condition allows to know if one element of L1 # was found between L2[i] and L2[i + 1]: # - if so, we have L1[i] < L2[i] < L1[i + 1] < L2[i + 1] # - else we have L1[i] < L2[i] < L1[i + 1] but # we don't know between L1[i + 1] and L2[i + 1] if L1[i11] < L2[i + 1]: L1 = L1[:i + 1] + [L1[i11]] + L1[i12:] index1, index2 = i + 1, i + 2 else: L1 = L1[:i + 1] + L1[i12:] index1, index2 = i, i + 1 # Do the same kind of symetric search, # with indexes computed above i21 = bisect.bisect_left(L2, L1[index1]) i22 = bisect.bisect_left(L2, L1[index2]) if L2[i21] < L1[index2]: L2 = L2[:index1] + [L2[i21]] + L2[i22:] else: L2 = L2[:index1] + L2[i22:] # Little trick not to test indexes everywhere: # lists are browsed at the same time except IndexError: pass # Next index ! i += 1 # Show result print 'L1:', L1, '- L2:', L2 >>> sort_relative([1, 10, 50], [15, 30]) L1: [1, 50] - L2: [15] >>> sort_relative([17, 18, 50], [15, 30]) L1: [15, 30] - L2: [17, 50] >>> sort_relative([1, 10, 12, 25, 27, 50], [15, 30, 70]) L1: [1, 25, 50] - L2: [15, 30, 70] >>> sort_relative([1, 10, 12, 25, 27, 50], [15, 30, 34, 70]) L1: [1, 25, 50] - L2: [15, 30, 70] >>> 

No tomé en cuenta el caso cuando un número está tanto en A como en B