I need to get only the permutations that have letters and numbers (The permutation can not be. \"A, B, C, D\" I need it like this: \"A, B, C, 1\")
In short, the perm
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)
I split them 3 digit-3letter, 2digit-2letter. So compile t and x is your answer.First for loop cant contain only numbers or only letters because its permutations 4. Second one cant also same reason.So compile the results in a list, means your answer.
How to calculate the time;
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")
Output:
...
...
...
('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
>>>
Edit for how much permutations are there:
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")
Output:
...
...
...
('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
>>>
Update the valid_data_types_in_list() function to add additional constraints on your list.
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
Using 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])
Quite a naive solution..
(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))
To use filter or ifilter, you must pass a predicate function and a sequence. The predicate function is evaluated once for each element in the sequence, and filter will only forward those elements which evaluate the predicate as True.
For instance, let's say you wanted only the uppercase letters in a string:
>>> def is_upper(c):
... return c.upper() == c
...
>>> uppers = filter(is_upper, "lsjdfLSKJDFLljsdlfkjLSFLDJ")
>>> print uppers
LSKJDFLLSFLDJ
Or if you only wanted the numbers that end in "6" in some list of numbers:
>>> 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]
(If you are not used to using lambdas, they are useful with filter when the logic is this simple. The lambda above is the same as:
def predicate(n):
return n % 10 == 6
nums_that_end_in_6 = filter(predicate, range(100))
In your situation, you are getting a sequence of combinations of letter and int values, and you only want those that are a mixture of letters and ints. So you will need to write a predicate function that returns True when given a sequence that is to your liking. Using the set-based solution, your predicate might look like:
ints = set(range(10))
letters = set(string.letters)
def predicate(seq):
seqset = set(seq)
return seqset & letters and seqset & ints
Using the any/all builtins, your predicate might look like:
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))
Or if you just want to see if your sequence contains items of more than 1 type, you could write:
def predicate(seq):
return len(set(type(item) for item in seq))) > 1
To use any of these predicates, the form is the same:
values = list(string.letters) + range(10)
mixed_letter_int_combinations = filter(predicate, combinations(values, 4))
Then you can choose which predicate you prefer, based on performance, or readability, or whatever other criteria you like.
You can generate the proper combinations by combining non-empty combinations from the two sequences.
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, n-i):
yield ca + cb
for r in combinations(list('abcd'), [1, 2, 3, 4], 4):
print r
The number of combinations you get is choose(A+B, n) - choose(A, n) - choose(B, n), where A is the number of elements in a, B the number of elements in b, and "choose" is the binomial coefficient.