More elegant solution to this challenge?

Hey All

Hope all is well in your world of code

I completed some coding challenge that I understand was based around using pythonic programming to solve it, but I couldn’t quite see an elegant solution to it and in the end basically ‘cheated’

This is the problem above, and below is my solution

``````def sublist(lst1, lst2):
ls1 = ""
ls2 = ""
for i in lst1:
ls1 += str(i) + ", "
for j in lst2:
ls2 += str(j) + ", "

print(ls1, ls2)

if ls1 == ls2:
return EQUAL
elif ls1 in ls2:
return SUBLIST
elif ls2 in ls1:
return SUPERLIST
else:
return UNEQUAL
``````

As you can see, I got around a lot of the difficulty using methods inherent to strings.

Is there any way this can be resolved using just list comprehension?

I particularly struggled with ensuring the preservation of order, otherwise, I would have just used a set and been done with it; this is the real bit that I couldn’t find a neat way to resolve.

``````    def test_first_list_missing_element_from_second_list(self):
self.assertEqual(sublist([1, 3], [1, 2, 3]), UNEQUAL)
``````

All suggestions are welcome!

D.W.

I don’t see how list comprehension would be of any benefit here.

I’d assume you compare the lengths and then just have a loop for every case.

Yeah, that was the alternative approach, using a for loop to compare and match values but the complexity becomes 0(n^2), and at this time I’m still not super familiar with more efficient algorithms, but I guess I’ll have to take this approach.

hm… worst case, maybe. Although you sure your code is more efficient? I mean, just because you use built-in functions doesn’t mean the don’t add complexity. It just means you didn’t “write” the complexity, but they still take it.

1 Like

Fair point hahaha, there isn’t always an elegant solution

This is the best I could come up with

``````def sublist_v2(list1, list2):
if list1 == list2:
return EQUAL
if len(list1) == 0:
return SUBLIST
if len(list2) == 0:
return SUPERLIST
if len(list1) == len(list2):
return UNEQUAL

# check for subset
if set(list1).issubset(set(list2)):
for i in range(len(list2)):
if list1[0] == list2[i]:
match = all([list1[j] == list2[i + j] for j in range(len(list1))])
if match:
return SUBLIST
elif set(list1).issuperset(set(list2)):
for i in range(len(list1)):
if list2[0] == list1[i]:
match = all([list2[j] == list1[i + j] for j in range(len(list2))])
if match:
return SUPERLIST

return UNEQUAL
``````
1 Like

Can you share a link to the challenge? I’d like to test some code if possible ^^

This shouldn’t work? Array-comparison goes by memory adress, not content. So even if the lists contain the exact same content, they would compare as unequal if they don’t happen to refer to the exact same object in memory.

The challenge is locked behind a paywall but I have the text shown above and the suite of tests you need to pass copied out below

As for the `==` operator, as far as I understand it does compare for literal equality (unlike in java) for arrays, the `is` keyword on the other hand looks at memory location

It isn’t clear in the documentation and almost contradictory but I did find this
https://docs.python.org/3/library/operator.html

``````import unittest

from sublist import sublist_v2 as sublist, SUBLIST, SUPERLIST, EQUAL, UNEQUAL

class SublistTest(unittest.TestCase):
def test_empty_lists(self):
self.assertEqual(sublist([], []), EQUAL)

def test_empty_list_within_non_empty_list(self):
self.assertEqual(sublist([], [1, 2, 3]), SUBLIST)

def test_non_empty_list_contains_empty_list(self):
self.assertEqual(sublist([1, 2, 3], []), SUPERLIST)

def test_list_equals_itself(self):
self.assertEqual(sublist([1, 2, 3], [1, 2, 3]), EQUAL)

def test_different_lists(self):
self.assertEqual(sublist([1, 2, 3], [2, 3, 4]), UNEQUAL)

def test_false_start(self):
self.assertEqual(sublist([1, 2, 5], [0, 1, 2, 3, 1, 2, 5, 6]), SUBLIST)

def test_consecutive(self):
self.assertEqual(sublist([1, 1, 2], [0, 1, 1, 1, 2, 1, 2]), SUBLIST)

def test_sublist_at_start(self):
self.assertEqual(sublist([0, 1, 2], [0, 1, 2, 3, 4, 5]), SUBLIST)

def test_sublist_in_middle(self):
self.assertEqual(sublist([2, 3, 4], [0, 1, 2, 3, 4, 5]), SUBLIST)

def test_sublist_at_end(self):
self.assertEqual(sublist([3, 4, 5], [0, 1, 2, 3, 4, 5]), SUBLIST)

def test_at_start_of_superlist(self):
self.assertEqual(sublist([0, 1, 2, 3, 4, 5], [0, 1, 2]), SUPERLIST)

def test_in_middle_of_superlist(self):
self.assertEqual(sublist([0, 1, 2, 3, 4, 5], [2, 3]), SUPERLIST)

def test_at_end_of_superlist(self):
self.assertEqual(sublist([0, 1, 2, 3, 4, 5], [3, 4, 5]), SUPERLIST)

def test_first_list_missing_element_from_second_list(self):
self.assertEqual(sublist([1, 3], [1, 2, 3]), UNEQUAL)

def test_second_list_missing_element_from_first_list(self):
self.assertEqual(sublist([1, 2, 3], [1, 3]), UNEQUAL)

def test_order_matters_to_a_list(self):
self.assertEqual(sublist([1, 2, 3], [3, 2, 1]), UNEQUAL)

def test_same_digits_but_different_numbers(self):
self.assertEqual(sublist([1, 0, 1], [10, 1]), UNEQUAL)

def test_unique_return_values(self):
self.assertEqual(len({SUBLIST, SUPERLIST, EQUAL, UNEQUAL}), 4)

def test_inner_spaces(self):
self.assertEqual(sublist(["a c"], ["a", "c"]), UNEQUAL)

def test_large_lists(self):
self.assertEqual(
sublist(
list(range(1000)) * 1000 + list(range(1000, 1100)),
list(range(900, 1050)),
),
SUPERLIST,
)

I would guess that == calls the `self.eq(other)` method embedded in all objects, and the implementation for LISTS is one that compares them literally? I keep calling them arrays but had to correct myself XD arrays are separate in python, though I’ve never used it I’ve heard it comes with numpy?