3

I have below code:

old_sqls = ["select * from T1", "select * from T2", "select * from T3"]
new_sql = ["SELECT * FROM T1", "SELECT * FROM T3", "SELECT * FROM T2"]

if old_sqls == new_sql:
    print("equals")
else:
    print("not equals")

its giving not equals I want result of this to equals. looking to ignore both order and case of strings used in list. Compare them regardless or order and case in one statement and print equals

costaparas
  • 5,047
  • 11
  • 16
  • 26

4 Answers4

2

If you want to compare general strings, to avoid issues with unicode, I suggest you normalize the strings and use casefold:

import unicodedata


def normalize_caseless(text):
    return unicodedata.normalize("NFKD", text.casefold())


old_sql = ["select * from T1", "select * from T2", "select * from T3"]
new_sql = ["SELECT * FROM T1", "SELECT * FROM T3", "SELECT * FROM T2"]

if set(map(normalize_caseless, old_sql)) == set(map(normalize_caseless, new_sql)):
    print("equals")
else:
    print("not equals")

Output

equals

You can see why this is useful, in this answer.

Also note that you could use a set, which makes the comparison O(n) (expected), although with larger constants. So this should be faster that O(nlogn) for larger lists.

Set will only work if there are not duplicates strings, for that case you could use collections.Counter:

import unicodedata
from collections import Counter

def normalize_caseless(text):
    return unicodedata.normalize("NFKD", text.casefold())


old_sql = ["select * from T1", "select * from T2", "select * from T3"]
new_sql = ["SELECT * FROM T1", "SELECT * FROM T3", "SELECT * FROM T2"]

if Counter(map(normalize_caseless, old_sql)) == Counter(map(normalize_caseless, new_sql)):
    print("equals")
else:
    print("not equals")
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
2

This looks like a good candidate for the use of Python sets.

old_sqls=["select * from T1","select * from T2","select * from T3"]
new_sql=["SELECT * FROM T1","SELECT * FROM T3","SELECT * FROM T2"]

if {e.upper() for e in old_sqls} == {e.upper() for e in new_sql}:
    print("equals")
else:
    print("not equals")

Note: This method only works if it doesn't matter how many times a list element occurs. See other answers' use of Python Counter objects if frequency is relevant. Thanks to Costaparas for pointing this out.

Caleb McNevin
  • 135
  • 1
  • 12
  • 2
    This is a very neat solution, but the caveat here is it doesn't consider the frequency of the list elements. Comparing lists and sets is not the same thing -- since elements of a list can be repeated and that would make them *different* whereas as sets, they'd be considered equal (of course it might not matter depending on the usage so this answer still has a lot of merit). – costaparas Dec 23 '20 at 11:09
2

Lower-casing and sorting is fine but sorting is log-linear. A linear approach would be counting and can be applied using collections.Counter:

 from collections import Counter

 if Counter(map(str.lower, old_sql)) == Counter(map(str.lower, new_sql)):
     # ...
user2390182
  • 72,016
  • 6
  • 67
  • 89
1

Try using sorted:

old_sqls = ["select * from T1", "select * from T2", "select * from T3"]
new_sql = ["SELECT * FROM T1", "SELECT * FROM T3", "SELECT * FROM T2"]

if sorted([i.lower() for i in old_sqls]) == sorted([i.lower() for i in new_sql]):
    print("equals")
else:
    print("not equals")

sorted sorts lists, so here I sort both lists, so the order should be the same if the two lists have the same values.

costaparas
  • 5,047
  • 11
  • 16
  • 26
U13-Forward
  • 69,221
  • 14
  • 89
  • 114