I've tried to be as detailed as possible. This should be an example how you can often work your way through such a problem by inserting a lot of print
messages to create a log of what's going on.
prefs = {
's1': ["a", "b", "c", "d", "e"],
's2': ["c", "d", "e", "a", "b"],
's3': ["a", "b", "c", "d", "e"],
's4': ["c", "d", "e", "b", "e"],
's5': ["c", "d", "e", "a", "b"]
}
# Get all items of prefs and sort them by key. (Sorting might not be
# necessary, that's something you'll have to decide.)
items_a = sorted(prefs.items(), key=lambda item: item[0])
# Make a copy of the items where we can delete the processed items.
items_b = items_a.copy()
# Set the length for each compared slice.
slice_length = 3
# Calculate how many comparisons will be necessary per item.
max_shift = len(items_a[0][1]) - slice_length
# Create an empty result list for all matches.
matches = []
# Loop all items
print("Comparisons:")
for key_a, value_a in items_a:
# We don't want to check items against themselves, so we have to
# delete the first item of items_b every loop pass (which would be
# the same as key_a, value_a).
del items_b[0]
# Loop remaining other items
for key_b, value_b in items_b:
print("- Compare {} to {}".format(key_a, key_b))
# We have to shift the compared slice
for shift in range(max_shift + 1):
# Start the slice at 0, then shift it
start = 0 + shift
# End the slice at slice_length, then shift it
end = slice_length + shift
# Create the slices
slice_a = value_a[start:end]
slice_b = value_b[start:end]
print(" - Compare {} to {}".format(slice_a, slice_b), end="")
if slice_a == slice_b:
print(" -> Match!", end="")
matches += [(key_a, key_b, shift)]
print("")
print("Matches:")
for key_a, key_b, shift in matches:
print("- At positions {} to {} ({} elements), {} matches with {}".format(
shift + 1, shift + slice_length, slice_length, key_a, key_b))
Which prints:
Comparisons:
- Compare s1 to s2
- Compare ['a', 'b', 'c'] to ['c', 'd', 'e']
- Compare ['b', 'c', 'd'] to ['d', 'e', 'a']
- Compare ['c', 'd', 'e'] to ['e', 'a', 'b']
- Compare s1 to s3
- Compare ['a', 'b', 'c'] to ['a', 'b', 'c'] -> Match!
- Compare ['b', 'c', 'd'] to ['b', 'c', 'd'] -> Match!
- Compare ['c', 'd', 'e'] to ['c', 'd', 'e'] -> Match!
- Compare s1 to s4
- Compare ['a', 'b', 'c'] to ['c', 'd', 'e']
- Compare ['b', 'c', 'd'] to ['d', 'e', 'b']
- Compare ['c', 'd', 'e'] to ['e', 'b', 'e']
- Compare s1 to s5
- Compare ['a', 'b', 'c'] to ['c', 'd', 'e']
- Compare ['b', 'c', 'd'] to ['d', 'e', 'a']
- Compare ['c', 'd', 'e'] to ['e', 'a', 'b']
- Compare s2 to s3
- Compare ['c', 'd', 'e'] to ['a', 'b', 'c']
- Compare ['d', 'e', 'a'] to ['b', 'c', 'd']
- Compare ['e', 'a', 'b'] to ['c', 'd', 'e']
- Compare s2 to s4
- Compare ['c', 'd', 'e'] to ['c', 'd', 'e'] -> Match!
- Compare ['d', 'e', 'a'] to ['d', 'e', 'b']
- Compare ['e', 'a', 'b'] to ['e', 'b', 'e']
- Compare s2 to s5
- Compare ['c', 'd', 'e'] to ['c', 'd', 'e'] -> Match!
- Compare ['d', 'e', 'a'] to ['d', 'e', 'a'] -> Match!
- Compare ['e', 'a', 'b'] to ['e', 'a', 'b'] -> Match!
- Compare s3 to s4
- Compare ['a', 'b', 'c'] to ['c', 'd', 'e']
- Compare ['b', 'c', 'd'] to ['d', 'e', 'b']
- Compare ['c', 'd', 'e'] to ['e', 'b', 'e']
- Compare s3 to s5
- Compare ['a', 'b', 'c'] to ['c', 'd', 'e']
- Compare ['b', 'c', 'd'] to ['d', 'e', 'a']
- Compare ['c', 'd', 'e'] to ['e', 'a', 'b']
- Compare s4 to s5
- Compare ['c', 'd', 'e'] to ['c', 'd', 'e'] -> Match!
- Compare ['d', 'e', 'b'] to ['d', 'e', 'a']
- Compare ['e', 'b', 'e'] to ['e', 'a', 'b']
Matches:
- At positions 1 to 3 (3 elements), s1 matches with s3
- At positions 2 to 4 (3 elements), s1 matches with s3
- At positions 3 to 5 (3 elements), s1 matches with s3
- At positions 1 to 3 (3 elements), s2 matches with s4
- At positions 1 to 3 (3 elements), s2 matches with s5
- At positions 2 to 4 (3 elements), s2 matches with s5
- At positions 3 to 5 (3 elements), s2 matches with s5
- At positions 1 to 3 (3 elements), s4 matches with s5
It's still unclear, what your output really should be. However, I think you'll have no problems in converting the above code to your needs.