0

The idea is to create a list of strings of a certain amount of characters preserving the order from the original list. The challenge is to accomplish it using only list comprehensions.

list_string = [ "aaa", "bb", "cc", "dd", "ee"]
str_len = 6
[some_list_comprehension]

The result should be something like ["aaabb", "ccddee"]. The string aaabb in the result list is 5 characters long, while the string ccddee is 6, that is because strings in the original list cannot be chunked. The order of the strings is relevant while creating the result, but irrelevant in the result, so that the end list could be ["ccddee", "aaabb"] but not ["eeddcc", "bbaaa"]. Each string appears in the result list just the same number of times as in the original, meaning that all possible combinations of the strings is not really the objective in this problem, mostly because each string in the result list is created following the order in the original. There are only 2 possible outputs:

["aaabb", "ccddee"]

or

["ccddee", "aaabb"]
4

2 回答 2

2

Ok, I think I got it, now. Is this what you were looking for?

>>> list_string = [ "aaa", "bb", "cc", "dd", "ee"]
>>> str_len = 6
>>> [[''.join(list_string[:i]), ''.join(list_string[i:])] for i in xrange(len(list_string)) if all(1 <= len(s) <= str_len for s in [''.join(list_string[:i]), ''.join(list_string[i:])])]
[['aaabb', 'ccddee']]

It yields all possible combinations that might have worked with one partitioning of the string. Here are all possible results:

>>> for str_len in range(len(''.join(list_string))):
        print str_len, [[''.join(list_string[:i]), ''.join(list_string[i:])] for i in xrange(len(list_string)) if all(1 <= len(s) <= str_len for s in [''.join(list_string[:i]), ''.join(list_string[i:])])]


0 []
1 []
2 []
3 []
4 []
5 []
6 [['aaabb', 'ccddee']]
7 [['aaabb', 'ccddee'], ['aaabbcc', 'ddee']]
8 [['aaa', 'bbccddee'], ['aaabb', 'ccddee'], ['aaabbcc', 'ddee']]
9 [['aaa', 'bbccddee'], ['aaabb', 'ccddee'], ['aaabbcc', 'ddee'], ['aaabbccdd', 'ee']]
10 [['aaa', 'bbccddee'], ['aaabb', 'ccddee'], ['aaabbcc', 'ddee'], ['aaabbccdd', 'ee']]

EDIT: Here is a version which uses filter but doesn't duplicate the result twice in the expression, and has nicer formatting:

>>> filter(
        lambda res: all(1 <= len(s) <= str_len for s in res),
        [[''.join(list_string[:i]), ''.join(list_string[i:])]
         for i in xrange(len(list_string))])
[['aaabb', 'ccddee']]
于 2012-07-13T20:53:07.513 回答
1
from itertools import combinations
list_string = [ "aaa", "bb", "cc", "dd", "ee"]
minn=min(map(len,list_string))
maxx=max(map(len,list_string))
str_len=6
lis=[''.join(x) for i in range(1,maxx+1) for x in combinations(list_string,i) if len(''.join(x))<=str_len]        
print lis

output:

['aaa', 'bb', 'cc', 'dd', 'ee', 'aaabb', 'aaacc', 'aaadd', 'aaaee', 'bbcc', 'bbdd', 'bbee', 'ccdd', 'ccee', 'ddee', 'bbccdd', 'bbccee', 'bbddee', 'ccddee']
于 2012-07-13T20:25:39.920 回答