Python Itertools permutaciones sólo letras y números

Necesito obtener solo las permutaciones que tienen letras y números (La permutación no puede ser. “A, B, C, D” Lo necesito así: “A, B, C, 1”)

En resumen, las permutaciones no pueden contener solo letras, no solo números. Debe ser una combinación de ambos.

Mi código:

import itertools print list(itertools.combinations([0,1,2,3,4,'a','b','c','d'], 4)) 

Entonces me sale:

 [(0, 1, 2, 3), (0, 1, 2, 4), (0, 1, 2, 'a'), (0, 1, 2, 'b'), (0, 1, 2, 'c'), (0, 1, 2, 'd'), (0, 1, 3, 4), (0, 1, 3, 'a'), (0, 1, 3, 'b'), (0, 1, 3, 'c'), (0, 1, 3, 'd'), (0, 1, 4, 'a'), (0, 1, 4, 'b'), (0, 1, 4, 'c'), (0, 1, 4, 'd'), (0, 1, 'a', 'b'), (0, 1, 'a', 'c'), (0, 1, 'a', 'd'), (0, 1, 'b', 'c'), (0, 1, 'b', 'd'), (0, 1, 'c', 'd'), (0, 2, 3, 4), (0, 2, 3, 'a'), (0, 2, 3, 'b'), (0, 2, 3, 'c'), (0, 2, 3, 'd'), (0, 2, 4, 'a'), (0, 2, 4, 'b'), (0, 2, 4, 'c'), (0, 2, 4, 'd'), (0, 2, 'a', 'b'), (0, 2, 'a', 'c'), (0, 2, 'a', 'd'), (0, 2, 'b', 'c'), (0, 2, 'b', 'd'), (0, 2, 'c', 'd'), (0, 3, 4, 'a'), (0, 3, 4, 'b'), (0, 3, 4, 'c'), (0, 3, 4, 'd'), (0, 3, 'a', 'b'), (0, 3, 'a', 'c'), (0, 3, 'a', 'd'), (0, 3, 'b', 'c'), (0, 3, 'b', 'd'), (0, 3, 'c', 'd'), (0, 4, 'a', 'b'), (0, 4, 'a', 'c'), (0, 4, 'a', 'd'), (0, 4, 'b', 'c'), (0, 4, 'b', 'd'), (0, 4, 'c', 'd'), (0, 'a', 'b', 'c'), (0, 'a', 'b', 'd'), (0, 'a', 'c', 'd'), (0, 'b', 'c', 'd'), (1, 2, 3, 4), (1, 2, 3, 'a'), (1, 2, 3, 'b'), (1, 2, 3, 'c'), (1, 2, 3, 'd'), (1, 2, 4, 'a'), (1, 2, 4, 'b'), (1, 2, 4, 'c'), (1, 2, 4, 'd'), (1, 2, 'a', 'b'), (1, 2, 'a', 'c'), (1, 2, 'a', 'd'), (1, 2, 'b', 'c'), (1, 2, 'b', 'd'), (1, 2, 'c', 'd'), (1, 3, 4, 'a'), (1, 3, 4, 'b'), (1, 3, 4, 'c'), (1, 3, 4, 'd'), (1, 3, 'a', 'b'), (1, 3, 'a', 'c'), (1, 3, 'a', 'd'), (1, 3, 'b', 'c'), (1, 3, 'b', 'd'), (1, 3, 'c', 'd'), (1, 4, 'a', 'b'), (1, 4, 'a', 'c'), (1, 4, 'a', 'd'), (1, 4, 'b', 'c'), (1, 4, 'b', 'd'), (1, 4, 'c', 'd'), (1, 'a', 'b', 'c'), (1, 'a', 'b', 'd'), (1, 'a', 'c', 'd'), (1, 'b', 'c', 'd'), (2, 3, 4, 'a'), (2, 3, 4, 'b'), (2, 3, 4, 'c'), (2, 3, 4, 'd'), (2, 3, 'a', 'b'), (2, 3, 'a', 'c'), (2, 3, 'a', 'd'), (2, 3, 'b', 'c'), (2, 3, 'b', 'd'), (2, 3, 'c', 'd'), (2, 4, 'a', 'b'), (2, 4, 'a', 'c'), (2, 4, 'a', 'd'), (2, 4, 'b', 'c'), (2, 4, 'b', 'd'), (2, 4, 'c', 'd'), (2, 'a', 'b', 'c'), (2, 'a', 'b', 'd'), (2, 'a', 'c', 'd'), (2, 'b', 'c', 'd'), (3, 4, 'a', 'b'), (3, 4, 'a', 'c'), (3, 4, 'a', 'd'), (3, 4, 'b', 'c'), (3, 4, 'b', 'd'), (3, 4, 'c', 'd'), (3, 'a', 'b', 'c'), (3, 'a', 'b', 'd'), (3, 'a', 'c', 'd'), (3, 'b', 'c', 'd'), (4, 'a', 'b', 'c'), (4, 'a', 'b', 'd'), (4, 'a', 'c', 'd'), (4, 'b', 'c', 'd'), ('a', 'b', 'c', 'd')] 

Haciendo esta pregunta, hágame saber si hay una forma posible de saber el tamaño del archivo obtenido, si quiero guardarlo en un archivo de texto. También quiero saber si hay alguna forma de calcular cuánto tiempo tomaría obtener todas las permutaciones que estoy pidiendo.

Muchas gracias por adelantado.

Usando set intersection:

 import itertools import string numbers = set(range(10)) letters = set(string.ascii_letters) print([x for x in itertools.combinations([0,1,2,3,4,'a','b','c','d'], 4) if set(x) & letters and set(x) & numbers]) 

Una solución bastante ingenua.

 (x for x in itertools.combinations([0,1,2,3,4,'a','b','c','d'], 4) if not all(c.isalpha() for c in x) and not all(c.isdigit() for c in x)) 

Actualice la función valid_data_types_in_list () para agregar restricciones adicionales a su lista.

 def valid_data_types_in_list(input_list): str_type = False int_type = False for element in input_list: if type(element) == str: str_type = True if type(element) == int: int_type = True if str_type == int_type == True: return True return False import itertools output = [x for x in list(itertools.combinations([0,1,2,3,4,'a','b','c','d'], 4)) if valid_data_types_in_list(x)] print output 
 mylist=[] for x in permutations([0,1,2,"a","b","c"],4): print (x) mylist.append(x) for t in permutations([3,4,"c","d"]): print (t) mylist.append(t) 

Los dividí en 3 dígitos, 3 boletines, 2 dígitos y 2 boletines. Entonces compile t y x es su respuesta. Primero para el bucle no puede contener solo números o solo letras debido a sus permutaciones 4. Segundo, no puede ser el mismo motivo. Así que compile los resultados en una lista, significa su respuesta.

Cómo calcular el tiempo;

 import time mylist=[] start=time.time() for x in permutations([0,1,2,"a","b","c"],4): print (x) mylist.append(x) for t in permutations([3,4,"c","d"]): print (t) mylist.append(t) end=time.time() diff=end-start print ("It took",diff,"seconds") 

Salida:

 ... ... ... ('c', 4, 'd', 3) ('c', 'd', 3, 4) ('c', 'd', 4, 3) ('d', 3, 4, 'c') ('d', 3, 'c', 4) ('d', 4, 3, 'c') ('d', 4, 'c', 3) ('d', 'c', 3, 4) ('d', 'c', 4, 3) It took 0.5800008773803711 seconds >>> 

Editar para cuántas permutaciones hay :

 from itertools import permutations import time mylist=[] start=time.time() for x in permutations([0,1,2,"a","b","c"],4): print (x) mylist.append(x) for t in permutations([3,4,"c","d"]): print (t) mylist.append(t) end=time.time() diff=end-start print ("There is {} permutations.".format(len(mylist))) print ("It took",diff,"seconds") 

Salida:

 ... ... ... ('d', 3, 4, 'c') ('d', 3, 'c', 4) ('d', 4, 3, 'c') ('d', 4, 'c', 3) ('d', 'c', 3, 4) ('d', 'c', 4, 3) There is 384 permutations. It took 0.5120010375976562 seconds >>> 

Para utilizar filtro o filtro de filtro, debe pasar una función de predicado y una secuencia. La función de predicado se evalúa una vez para cada elemento en la secuencia, y el filtro solo reenviará aquellos elementos que evalúen el predicado como Verdadero.

Por ejemplo, digamos que solo deseaba las letras mayúsculas en una cadena:

 >>> def is_upper(c): ... return c.upper() == c ... >>> uppers = filter(is_upper, "lsjdfLSKJDFLljsdlfkjLSFLDJ") >>> print uppers LSKJDFLLSFLDJ 

O si solo quiere los números que terminan en “6” en alguna lista de números:

 >>> nums_that_end_in_6 = filter(lambda n: n % 10 == 6, range(100)) >>> print nums_that_end_in_6 [6, 16, 26, 36, 46, 56, 66, 76, 86, 96] 

(Si no estás acostumbrado a usar lambdas, son útiles con el filtro cuando la lógica es así de simple. La lambda anterior es la misma que:

 def predicate(n): return n % 10 == 6 nums_that_end_in_6 = filter(predicate, range(100)) 

En su situación, está obteniendo una secuencia de combinaciones de valores de letra e int, y solo desea aquellos que son una mezcla de letras y letras. Por lo tanto, deberá escribir una función de predicado que devuelva Verdadero cuando se le asigne una secuencia que sea de su agrado. Usando la solución basada en conjuntos, su predicado podría verse así:

 ints = set(range(10)) letters = set(string.letters) def predicate(seq): seqset = set(seq) return seqset & letters and seqset & ints 

Usando cualquiera o todos los elementos incorporados, su predicado podría verse así:

 is_int = lambda x : isinstance(x, int) is_str = lambda x : isinstance(x, str) def predicate(seq): return not(all(is_int(item) for item in seq) or all(is_str(item) for item in seq)) 

O si solo quiere ver si su secuencia contiene elementos de más de 1 tipo, podría escribir:

 def predicate(seq): return len(set(type(item) for item in seq))) > 1 

Para usar cualquiera de estos predicados, la forma es la misma:

 values = list(string.letters) + range(10) mixed_letter_int_combinations = filter(predicate, combinations(values, 4)) 

Luego, puede elegir el predicado que prefiera, según el rendimiento, la legibilidad o cualquier otro criterio que desee.

Puede generar las combinaciones adecuadas combinando combinaciones no vacías de las dos secuencias.

 import itertools def combinations(a, b, n): for i in xrange(1, n): for ca in itertools.combinations(a, i): for cb in itertools.combinations(b, ni): yield ca + cb for r in combinations(list('abcd'), [1, 2, 3, 4], 4): print r 

El número de combinaciones que obtiene es elegir (A + B, n): elija (A, n) – elija (B, n), donde A es el número de elementos en a, B el número de elementos en b, y ” elegir “es el coeficiente binomial.