Python Itertools permutations only letters and numbers

后端 未结 6 1128
無奈伤痛
無奈伤痛 2021-01-13 12:42

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

6条回答
  •  没有蜡笔的小新
    2021-01-13 13:29

    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.

提交回复
热议问题