简体   繁体   中英

Python Itertools permutations only letters and numbers

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 permutations can not contain only letters, not just numbers. Must be a combination of both.

My code:

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

Then I get:

[(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')]

I pushing this question, let me know if there is a possible way of knowing the size of the file obtained, if I want to save to a text file. I also want to know if there is any way to calculate how long it would take to get all permutations'm asking.

Thank you very much in advance.

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))
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 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM