2016-10-02 2 views
4

Я пытаюсь создать функцию, которая меняет порядок элементов в списке, а также отменяет элементы в подсписке. например:Как отменить элементы в подсписке?

Например, если L = [[1, 2], [3, 4], [5, 6, 7]], то deep_reverse (L) мутирует L как [[7, 6, 5 ], [4, 3], [2, 1]]

Я выяснил, как изменить порядок одного списка, но у меня возникают проблемы с изменением порядка элементов в подсписке. Это то, что я до сих пор:

def deep_reverse(L) 
    """ 
    assumes L is a list of lists whose elements are ints 
    Mutates L such that it reverses its elements and also 
    reverses the order of the int elements in every element of L. 
    It does not return anything. 
    """ 
    for i in reversed(L): 
      print(i) 

В приведенном выше примере, мой код будет просто напечатать [5,6,7], [3,4], [1,2], который не то, что я пытаюсь сделать. Это просто отменяет порядок списков, а не фактические элементы в списках.

Что я должен добавить в код, чтобы он также менял порядок элементов в подсписке?

[EDIT: мой код нуждается в, чтобы изменить список; Я не хочу просто напечатать его, он на самом деле нужно изменить список.]

+0

Спасибо за помощь, всем! Я отметил, что Чарльз ответил правильно, но я также получил много полезной обратной связи от geo1230, а Stefan Pochmann – EllaP

ответ

0

Это выглядит очень знакомым :). Я не собираюсь давать все рабочее решение, но вот несколько советов:

Как вы знаете, есть два шага, отменить каждый под-список и затем перевернуть внешний список (вместо того, чтобы создавать новый список , поэтому он будет мутировать глобальный L).

Таким образом, вы можете петлю через внешний список, и мутировать каждый вложенный список:

for i in range(len(L)): 
    # if L[i] is a list: 
     # reverse with [::-1] and update L[i] to the reversed version 
# reverse the outer list L, list.reverse() will operate in-place on L 

Теперь помните, если вы перебрать список, как это:

for item in list: 
    item = 'xxx' 

Вы не можете изменить item с вышеуказанным кодом. item - значение заполнитель, поэтому его изменение фактически не изменяет список.

Вы должны индексировать товар в L, и перечисление может помочь с этим, или вы можете использовать менее предпочтительный range(len()), как указано выше.

for i, item in enumerate(L): 
    # do something with L[i] 
    L[i] = 'something' 

Edit: так как есть так много путаницы по этому поводу, я буду идти вперед и опубликовать рабочее решение, основанное на очень элегантный ответ Стефан Pochmann в:

def deep_reverse(L): 
    L.reverse() 
    for sublist in L: 
     sublist.reverse() 

Извещение есть нет return statement, а также заявление на печать. Это правильно изменит L на месте. Вы не можете переназначить L внутри функции, потому что тогда он просто создаст новую локальную версию L, и он не будет изменять глобальный L. Вы можете использовать list.reverse() для изменения Lна месте, который необходим на основе спецификаций.

4
[sublist[::-1] for sublist in to_reverse[::-1]] 

Список понимание работы здесь. [::-1] в основном то же самое, что и reversed, но не изменяет список.

EDIT:

Как указано ниже, reversed не изменяет список. Она возвращает listreverseiterator объект

Больше Edit:

Если вы хотите решение для списков произвольной глубины, попробуйте:

def deep_reverse(to_reverse): 
    if isinstance(to_reverse, list): 
     return list(map(deep_reverse, to_reverse[::-1])) 
    else: 
     return to_reverse 

Еще более Edit:

Чтобы мутировать список в функция:

L[:] = new_list 

Измените список на месте.

+3

'reverseed' также не изменяет список. – user2357112

+1

Решение редактирования не изменяет 'L', просто возвращает обратную версию. Проверьте спецификации OP, это не требуется. – Charles

+0

Чтобы мутировать список, сделайте 'to_reverse.reverse()' перед 'map' и опустите' [:: - 1] ' –

-1

Вы можете сделать это рекурсивным, поэтому он будет работать для сколь угодно глубоких гнезд.

что-то вроде (непроверенные):

def deep_reverse(L) 
    """ 
    assumes L is a list of lists whose elements are ints 
    Mutates L such that it reverses its elements and also 
    reverses the order of the int elements in every element of L. 
    It does not return anything. 
    """ 
    for i in reversed(L): 
      if len(i) > 1: 
       deep_reverse(i) 
      else: 
       print(i) 
+0

'len' не' длина'. Кроме того, 'len (int)' будет поднять 'TypeError' –

+0

Вы, вероятно, хотите' if isinstance (i, list) и len (i)> 1' или что-то в этом роде. – Charles

+0

wow ваш быстрый, спасибо. – Smitje

1

Это должно сделать трюк.

L = [[1, 2], [3, 4], [5, 6, 7]] 

def deep_reverse(L): 
    for i in range(len(L)): 
     L[i]=L[i][::-1] 
    L=L[::-1] 
    return L 
+0

@EllaP Что вы подразумеваете под «mutate»? Если вы имеете в виду переустановка списка так, как вы хотите, тогда да. Кроме того, способ записи этого кода может быть использован без его модификации независимо от количества подписок или количества элементов в подсписках. Надеюсь, это помогло! – geo1230

+0

Я считаю, что это просто отменяет порядок элементов подписок. Код также должен отменить фактические подсписки в списке. – EllaP

+0

(я удалил предыдущий комментарий, потому что понял, что он мутирует список, как хотелось бы.) – EllaP

1

В качестве альтернативы вы используете map() для достижения этого, как:

>>> map(lambda x: x[::-1], L[::-1])  # In Python 2.x 
[[7, 6, 5], [4, 3], [2, 1]] 

>>> list(map(lambda x: x[::-1], L[::-1])) # In Python 3.x 
[[7, 6, 5], [4, 3], [2, 1]] 

Проверьте блог на Lambda, filter, reduce and map, чтобы узнать, как lambda функции и map() работает в Python.

2

I'm trying to create a function that reverses the order of the elements in a list, and also reverses the elements in a sublist.

Затем сделать именно эти две вещи:

L.reverse() 
for sublist in L: 
    sublist.reverse() 

Полное демо, потому что вы, кажется, путают о том, что ваша функция должна делать и как проверить:

>>> def deep_reverse(L): 
     """ 
     assumes L is a list of lists whose elements are ints 
     Mutates L such that it reverses its elements and also 
     reverses the order of the int elements in every element of L. 
     It does not return anything. 
     """ 
     L.reverse() 
     for sublist in L: 
      sublist.reverse() 

>>> L = [[1, 2], [3, 4], [5, 6, 7]] 
>>> deep_reverse(L) 
>>> print(L) 
[[7, 6, 5], [4, 3], [2, 1]] 
+0

как я могу это вернуть? – EllaP

+0

@EllaP С 'return L'? –

+0

Да, но внутри или снаружи петли for? я просто хочу убедиться. – EllaP

0

с функциональной парадигмой и защитным программированием:

def deep_reverse(L): 
    """ assumes L is a list of lists whose elements are ints 
    Mutates L such that it reverses its elements and also 
    reverses the order of the int elements in every element of L. 
    It does not return anything. 
    """ 
    # Your code here 
    for i in L: 
     try: 
      deep_reverse(i) 
     except: 
      pass 
    L.reverse() 
Смежные вопросы