3
\$\begingroup\$

I have the following concise-ish (and working) approach to getting all the forward permutations of a list of string. So with the list:

w = ["Vehicula", "Sem", "Risus", "Tortor"]

the results should be:

['Vehicula', 'Vehicula Sem', 'Vehicula Sem Risus', 'Vehicula Sem Risus Tortor', 'Sem', 'Sem Risus', 'Sem Risus Tortor', 'Risus', 'Risus Tortor', 'Tortor']

To do this, we loop through each element, and perform an inner loop that looks ahead and saves slices of the remaining elements to a result array.

w = ["Vehicula", "Sem", "Risus", "Tortor"]
results = []

i = 0
l = len(w)
while i < l:
    j, k = i, i + 1
    while k <= l:
        results.append(" ".join(w[j:k]))    
        k = k + 1
    i = i + 1
print results

With Python, I always feel like I'm missing a trick, so I'm curios to see if there are any native Python functions that will make this more efficient?

Edit

I tested all three with timeit and mine is definitely the slowest. I've got to get to grips with itertools - it is very powerful.

Verbose (Mine): 3.61756896973
Comprehensions: 3.02565908432
Itertools: 2.83112883568
\$\endgroup\$
5
\$\begingroup\$

Here's an alternative approach using itertools.combinations to generate the (start, end) pairs:

from itertools import combinations
w = "Vehicula Sem Risus Tortor".split()
results = [' '.join(w[i:j]) for i, j in combinations(range(len(w) + 1), 2)]
\$\endgroup\$
1
\$\begingroup\$

This should work. I don't know if it is more readable than your approach though.

w = ["Vehicula", "Sem", "Risus", "Tortor"]
results = [' '.join(w[i:i+j+1]) for i in range(len(w)) for j in range(len(w)-i)]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.