I have two lists:
expected = ["apple", "banana", "pear"]
actual = ["banana_yellow", "apple", "pear_green"]
I'm trying to assert that expected = actual. Even though the color is added at the end to some elements, it should still return true.
Things I tried:
for i in expected:
assert i in actual
I was hoping something like this would work but it's trying to match the first element apple to banana and returns false rather than checking the entire list and returns true if there is apple anywhere in the list. I was hoping someone can help?
CodePudding user response:
I suggest a custom assertion method..
This is a bit more than you need, but also a bit more flexible.
- Order of the entries is irrelevant
- How the color is added is irrelevant (e.g. by dash, underscore, ...)
It still has the flaw that, if you have the color orange
added to carot
and are looking for orange
, it would also assert sucessfully. For such cases you need to tailor the method to your actual needs. (e.g. replace the substring in string
by string.startwith(substring)
etc. However, this should give you a starting point:
def assert_matching_list_contents(expected: list, actual: list) -> None:
if len(expected) != len(actual):
raise AssertionError('Length of the lists does not match!')
for expected_value in expected:
if not any(expected_value in entry for entry in actual):
raise AssertionError(f'Expected entry "{expected_value}" not found')
expectation = ["apple", "banana", "pear"]
current = ["banana_yellow", "apple", "pear_green"]
assert_matching_list_contents(expectation, current)
CodePudding user response:
You can use .startswith
, along with sorted lists to find it.
expected = ["apple", "banana", "pear"]
actual = ["banana_yellow", "apple", "pear_green"]
expected.sort() # just looking for prefixes
actual.sort()
count = 0
for i in actual:
if i.startswith(expected[count]): # prefix matches!
count =1 # move to next prefix
if count != len(expected): # since it didn't find all expected
print("Nope!")
assert False
It works because it just skips extras in actual
, but count
gets stuck if it can't find the prefix in actual
, leading count
to never reach the end of expected
.
CodePudding user response:
Try this:
def isequal(actual: list, expected: list) -> bool:
actual.sort()
expected.sort()
if len(actual) != len(expected):
return False
for i, val in enumerate(expected):
if not actual[i].startswith(val):
return False
return True
print(isequal(actual, expected))
CodePudding user response:
expected = ["apple", "banana", "pear"]
actual = ["banana_yellow", "apple", "pear_green", 'orange']
for act in actual:
if not act.startswith(tuple(expected)):
print(act)
>>>
orange
If you want it to work in the opposite way,
expected = ["apple", "banana", "pear", 'grapes']
actual = ["banana_yellow", "apple", "pear_green", 'orange']
expected_ = set(expected)
for act in actual:
for exp in expected:
if act.startswith(exp):
expected_.discard(exp)
break
assert not(expected_), f"{expected_} are not found in actual and " f"{set(expected)-expected_} are found in actual"
>>>
AssertionError: {'grapes'} are not found in actual and {'apple', 'pear', 'banana'} are found in actual
Another way,
expected = ["apple", "banana", "pear", 'grapes']
actual = ["banana_yellow", "apple", "pear_green", 'orange']
for exp in expected:
assert [exp for act in actual if act.startswith(exp)], f'{exp} not found'
>>>
AssertionError: grapes not found