简体   繁体   English

Python:获取列表的顺序元素的所有组合

[英]Python: Get all combinations of sequential elements of list

Given an array say x = ['A','I','R'] I would want output as an 给定一个数组,说x = ['A','I','R']我想将输出作为

[['A','I','R'],['A','I'],['I','R'],['A'],['I'],['R']]

What I don't want as output is : 我不想作为输出是:

[['A','I','R'],['A','I'],['I','R'],['A','R'],['A'],['I'],['R']]  # extra ['A','R'] which is not in sequence .

Below is the code which gives the output I don't want: 下面是提供不需要的输出的代码:

letter_list = [a for a in str]
all_word = []
for i in xrange(0,len(letter_list)):
    all_word = all_word + (map(list, itertools.combinations(letter_list,i))) # dont use append. gives wrong result.
all_word = filter(None,all_word) # remove empty combination
all_word = all_word + [letter_list] # add original list

My point is I only want combinations of sequences. 我的观点是我只想要序列的组合。 Is there any way to use itertools or should I write custom function ? 有什么方法可以使用itertools还是应该编写自定义函数?

Try to use yield : 尝试使用yield

x = ['A','I','R']

def groupme(x):
    s = tuple(x)
    for size in range(1, len(s) + 1):
        for index in range(len(s) + 1 - size):
            yield list(x[index:index + size])

list(groupme(x))

>>> [['A'], ['I'], ['R'], ['A', 'I'], ['I', 'R'], ['A', 'I', 'R']]

Yes, you can use itertools : 是的,您可以使用itertools

>>> x = ['A', 'I', 'R']
>>> xs = [x[i:j] for i, j in itertools.combinations(range(len(x)+1), 2)]
>>> xs
[['A'], ['A', 'I'], ['A', 'I', 'R'], ['I'], ['I', 'R'], ['R']]
>>> sorted(xs, key=len, reverse=True)
[['A', 'I', 'R'], ['A', 'I'], ['I', 'R'], ['A'], ['I'], ['R']]

Credit: answer by hochl 信用: hochl回答

don't try to be so magical: two loops will do what you want; 不要试图变得如此神奇:两个循环可以完成您想要的; one over possible sequence starts, the inner over possible sequence lengths: 一个超过可能的序列开始,内部超过可能的序列长度:

x = "AIR" # strings are iterables/sequences, too!
all_words = []
for begin in xrange(len(x)):
    for length in xrange(1,len(x) - begin+1):
        all_words.append(x[begin:begin+length])

using list comprehension: 使用列表理解:

letters=['A', 'I', 'R']
[letters[start:end+1] 
 for start in xrange(len(letters)) 
 for end in xrange(start, len(letters))]

[['A'], ['A', 'I'], ['A', 'I', 'R'], ['I'], ['I', 'R'], ['R']]

if it is important to have the order you proposed (from longest to shortest and when the same length by starting position) you can do instead: 如果拥有建议的顺序很重要(从最长到最短,并且起始位置的长度相同),则可以改为:

[letters[start:start+l+1]
 for l in range(len(letters))[::-1]
 for start in xrange(len(letters)-l)]

[['A', 'I', 'R'], ['A', 'I'], ['I', 'R'], ['A'], ['I'], ['R']]

Just to address Holroy comment. 只是为了解决Holroy的评论。 If instead of using list comprehension you use a generator expression (just substituting external [] with () ) you would get a much less memory requiring code. 如果不是使用列表推导,而是使用生成器表达式(仅将外部[]替换为() ),则所需的内存将大大减少。 But in this case you must be careful of not using the result more than once or for instance not trying to use list methods (such as len, or removing elements) on the result. 但是在这种情况下,您必须小心不要多次使用结果,或者例如不要尝试在结果上使用列表方法(例如len或删除元素)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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