#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)