сравнение двух списков рекрутингово

#python #list #recursion #multidimensional-array #comparison

#питон #Список #рекурсия #многомерный массив #сравнение

Вопрос:

мой профессор дал мне задание на python сравнить 2 двумерных списка, вернуть значение True, если все объекты в списках похожи, и значение False, если это не так. списки имеют тип — список[список[int]]. это должно быть сделано с помощью рекурсии. Мне не разрешается использовать петли или нарезку. (но может получить доступ к определенному индексу в списке) внутреннее разделение списков может отличаться, но до тех пор, пока все элементы в одинаковых местах в списке одинаковы, функция вернет значение True. например- [[1], [2, 3, 4]] , [[1, 2], [3, 4]] — функция вернет значение true. Я надеюсь, что детали ясны, спасибо!

мой вопрос заключается в том, чтобы найти решение этой проблемы 🙂

Комментарии:

1. На самом деле, это немного бессмысленная задача в Python, потому что Python может сравнивать вложенные списки со своим == оператором … — Вы могли бы в шутку написать def compare(lol1, lol2): return lol1 == lol2 — это определенно рабочее решение на Python 😉 .

2. Это на самом деле отличное задание на python! Спасибо, что поделились. Но у вас есть вопрос?

3. @Gwang-JinKim Насколько я понимаю постановку проблемы, ваше «решение» вообще не сработало бы.

4. ха-ха, к сожалению, большинство наших задач бессмысленны, они предназначены только для того, чтобы заставить нас усердно работать без всякой причины… я могу использовать только == для сравнения int в списках, а не самих списков 🙁

5. Я имел в виду в шутку — такого рода задания, как правило, из разных языков. Но для рекурсии вам нужно сравнить первый элемент списка ( car на лиспе) и остальную часть списка ( cdr ) — но проблема в том, что вам не разрешено использовать нарезку … и как вы можете взять остальную часть списка, не разрезая его? …

Ответ №1:

Обычно вы делаете l[0] и l[1:] для car и cdr ( first и rest ) из списка.

Самой большой проблемой в этой задаче является запрет нарезки.

Но с

 first, *rest = your_list   

Это работает! Не только без нарезки, но и без индексации.

 def first(l): # traditionally in Lisp languages `CAR`  car, *cdr = l  return car   def rest(l): # traditionally in Lisp languages `CDR`  car, *cdr = l  return cdr  def comp(lol1, lol2):  if len(lol1) == len(lol2) == 0: # recursion end condition  return True  # if first elements are lists, `comp`are the firsts and the rests  elif type(first(lol1)) == type(first(lol2)) == list:  return comp(first(lol1), first(lol2)) and   comp(rest(lol1), rest(lol2))  # if first elements are atoms (non-lists), `==` the firsts and `comp`are the rest  else: # then the firsts are atoms!  return first(lol1) == first(lol1) and   comp(rest(lol1), rest(lol2))   # traditionally in Lisp languages, you test not for list # but for `atom` (whether the first elements of the lists are # non-lists -gt; atomar). But `atom` is not that easy test in Python. # so it is must more easy to ask whether both first elements are lists - and  # if not - then it is clear that the first elements of non-empty lists must be non-lists =gt; atoms.       

Это работает с Python3, но не с Python2.

Для Python2 и Python3 вы можете использовать определения функций:

 def first(l):  return (lambda x, *y: x)(*l)  def rest(l):  return (lambda x, *y: y)(*l)  

С одной индексацией и .pop()

Возможно, то, о чем думал ваш учитель, было:

 def first(l):  return l[0]   def rest(l):  if l != []:  l.pop()  return l  else:  return []  # For definition of the `comp()` function see above  

Но это решение проблематично, потому что оно изменяет список входных данных, поскольку Python делает call-by-reference это и не call-by-value делает . Чтобы избежать этого, сначала нужно глубоко скопировать список. Можно мелко скопировать список с помощью нарезки, но нарезка не допускается …

Нравится:

 q = [1, 2, [3, 4], [5, 6, 7], 8] comp(q, q) ## True # so far so good, but: q ## []  

Ответ №2:

 a1 = [[1], [2, 3, 4]] a2 = [[1, 2], [3, 4]]  def get_next_indexes(i, j, a): # function for getting next indexes based on previous  return (i   1, 0)if j gt;= len(a[i]) - 1 else (i, j   1)  def compare_lists(i1, j1, i2, j2): # i1 and j1 - indexes for first array; i2 and j2 - indexes for second array  if i1 gt;= len(a1) or i2 gt;= len(a2):  print("Two lists are equal.")  exit(0)  if a1[i1][j1] != a2[i2][j2]:  print("Two lists are not equal.")  exit(0)  print(get_next_indexes(i1, j1, a1))  compare_lists(*get_next_indexes(i1, j1, a1), *get_next_indexes(i2, j2, a2))  compare_lists(0, 0, 0, 0)