Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Python] Сдвиги влево и вправо


Автор: Paranorma 20.1.2007, 19:57
Люди!
Я снова к вам обращаюсь за помощью! Простите меня, бестолковую!

Задание заключается вот в чем:

имеется список:

Код

a = [45, 34, 12, 10, 15]


количество элементов в списке увеличиваться и уменьшаться не должно. Но в нем должен происходить сдвиг влево, т.е. второй элемент становиться первым, последний - предпоследним, затем следовать 0. СТРОГО НАСТРОГО ЗАПРЕЩЕНО ИСПОЛЬЗОВАТЬ МЕТОДЫ DEL И APPEND. То есть я поняла, что происходить переприсваивание. Элементу с индексом 0 присвоить значение элемента с индексом 1, элементу с индексом 1 присвоить значение элемента с индексом 2 и т.д.

то есть в калькуляторе это будет выглядеть так:

Код

[34, 12, 10, 15, 0]
[12, 10, 15, 0, 0]
[10, 15, 0, 0, 0] 


Эта задача снова на использование цикла while, причем один в другом.
Я как-то недавно писала о задаче с удалением дубликатов:

Код

 a = [45, 1, 34, 12, 45, 45, 12, 1, 34, 10, 15, 15]
i = 0
while i < len(a)-1:
    j = i+1
    while j < len(a):
        if a[i] == a[j]: 
            del a[j]
        else:
            j = j + 1
    i = i + 1
print a


Насколько я понимаю, она очень похожа на эту, но тут мне не совсем понятно, как в новом задании поступать с переменными i и j. 

Автор: Void 20.1.2007, 22:21
В чём проблема?
Код
a = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(a) - 1:
    a[i] = a[i + 1]
    i += 1
a[i] = 0

Или даже так smile
Код
a = a[1:] + [0]

Автор: Paranorma 21.1.2007, 17:38
Проблема в том, что при всем чтении учебников я едва понимаю, как все это работает.

А как быть, если сдвиг нужен в обратную сторону?
 Т.е. вместо [1, 2, 3, 4, 5, 6] получить [0, 1, 2, 3, 4, 5]  

Автор: Void 21.1.2007, 17:52
Код
a = [1, 2, 3, 4, 5, 6]
i = len(a) - 1
while i > 0:
    a[i] = a[i - 1]
    i -= 1
a[i] = 0


А можно поинтересоваться, какими именно учебниками пользуетесь?

Автор: Paranorma 21.1.2007, 18:53
Void, спасибо, что помогаете мне. Наверно, я вас совсем замучила. smile 
Я пользуюсь Tutorial в самой программе, "Язык программирования Python",
авторы Россум, Дрейк, Откидач (тот же Tutorial, только по русски), "Учимся программировать вместе с Питоном", автор Чаплыгин А.Н.

Теоретической частью я более или менее овладела, а вот применить знания на практике не получается, почти никогда ничего не работает.

Препод велел еще сделать циклические сдвиги, когда в первом случае список [1, 2, 3, 4, 5, 6] превращается в [6, 1, 2, 3, 4, 5], а в другом превращается [2, 3, 4, 5, 6, 1] 

Увы, даже такие элементарные вещи не получаются. smile    

Автор: Void 22.1.2007, 16:53
Циклический сдвиг:
Код
# влево
a[-1] = a[0] # эквивалентно a[len(a) - 1] = a[0]
i = 0
while i < len(a) - 1:
    a[i] = a[i + 1]
    i += 1

# вправо
a[0] = a[-1]
i = len(a) - 1
while i > 0:
    a[i] = a[i - 1]
    i -= 1

Цитата(Paranorma @  21.1.2007,  20:53 Найти цитируемый пост)
Россум, Дрейк, Откидач (тот же Tutorial, только по русски), "Учимся программировать вместе с Питоном"

Посмотрел, неплохое руководство. Могу только пожелать удачи.

Автор: Paranorma 23.1.2007, 01:01
Да, по Чаплыгину книга вообще хорошая.


А как превратить a = [1, 2, 3, 4, 5, 6] в a = [6, 5, 4, 3, 2, 1]???

Могу конечно и так написать, но мне то через while надо:

Код

a=[1, 2, 3, 4, 5, 6]
a[-1] = 1
a[-2] = 2
a[-3] = 3
a[-4] = 4
a[-5] = 5
a[-6] = 6
print a

Автор: doomik 23.1.2007, 15:43
Какое условие задачи ? 
Я вижу 2
  •  Отсортировать элементы по убыванию
  •  Перевернуть массив
Догадываюсь что надо второй вариант написать:

Программа копирует элементы их массива a[] в a2[] в обратном порядке, дальше освобождаем массив 
a[] от его старых элементов а потом присваиваем ему элементы массива a2[]

Код

a = [1, 2, 3, 4, 5, 6]
a2 = [] # Создаем дополнительный массив
I = len(a)-1 # Запоминаем длинну a[] массива в I
aLen = len(a) # Запоминаем длинну a[] массива в aLen

while I > -1: # Читаем каждый элемент в масиве a[] и присваиваем его в массив a2[]
    a2.append(a[I])
    I -= 1

I = 0

while I != len(a): # Удаляем все элементы в массиве a[] чтоб потом заполнить его новыми элементами
    del(a[I])
    
I = 0 

while I != aLen: # Копируем элементы массива a2[] в массив a[]
    a.append(a2[I])
    I += 1

print a 


Автор: Void 23.1.2007, 17:20
Просто меняем местами симметричные элементы.
Код
def reverse(a):
    while i < len(a) / 2:
        t = a[i]
        a[i] = a[-i - 1]
        a[-i - 1] = t
        i += 1

Автор: Paranorma 23.1.2007, 21:15
Код

a = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(a) / 2:
    t = a[i]
    a[i] = a[-i - 1]
    a[-i - 1] = t
    i = i + 1
print a

Ну вот такая она у меня вышла... Вроде, работает!

Автор: pythonwin 24.1.2007, 10:23
Void, ++1 за помощь Paranorma с питоном

Автор: albertn 24.1.2007, 12:19
А не проще ли использовать код типа:
Код

s = [1,2,3,4,5,6]
print s[1:]+[s[0]]
print [s[-1]]+s[:-1]

Автор: Void 24.1.2007, 17:43
albertn, разумеется. Но дело в том, что
Цитата(Paranorma @  20.1.2007,  21:57 Найти цитируемый пост)
Эта задача снова на использование цикла while

и так далее в таком духе.
Я не считаю этот способ преподавания правильным, но c'est la vie.

Автор: V.A.KeRneL 24.1.2007, 17:53
Цитата(Void @  24.1.2007, 17:43 Найти цитируемый пост)

Я не считаю этот способ преподавания правильным, но c'est la vie.

Ну почему же? На ранних стадиях обучения программированию, которые, очевидно, осваивает Paranorma, главное — научиться придумыват и реализовывать своими руками элементарные алгоритмы, пользуясь примитивами, а не [сколь бы то ни было] продвинутыми методами и фишками языка.

Вот моё «безопасное» (не портящее массив-аргумент, а создающее новый) решение для задачи реверса массива (списка): 
Код

def reverse(a):
    b = []
    i = len(a) - 1
    while (i >= 0):
        b.append(a[i])
        i -= 1
    return b


Ниже приведено понравившееся мне решение задачи левого и правого сдвигов массива (списка) slav0nic'а с форума http://python.com.ua/forum/.

>>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>>
Код

def left_move(a, n):
    """
    a - список
    n - на сколько сдвигать
    """
 
    while n:
        a = a[1:] + [a[0]]
        n -= 1
    return a
 
 
def right_move(a, n):
    while n:
        a = [a[-1]] + a[:-1]
        n -= 1
    return a
 
 
a = [1, 2, 3, 4, 5, 6]
print a
print "<< 2", left_move(a, 2)
print ">> 2", right_move(a, 3)


Код

> /usr/bin/python -u "/tmp/1.py"
[1, 2, 3, 4, 5, 6]
<< 2 [3, 4, 5, 6, 1, 2]
>> 2 [4, 5, 6, 1, 2, 3]


имхо так покрасивше В)
сдвигается по 1 элементу за цикл

slav0nic = {jid: "[email protected]",
                 home: "http://slav0nic.xss.ru",
                 LJ: "http://slav0nic.livejournal.com"}
<<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<< <<<

Я бы переписал его так (для «безопасности»): 
Код

def simple_dup(a): 
    b = []
    for x in a: 
        b.append(x)
    return b


def left_move(a, n): 
    """
    a - список
    n - на сколько сдвигать
    """
    
    b = simple_dup(a)
    
    while n: 
        b = b[1:] + [b[0]]
        n -= 1
    
    return b


def right_move(a, n): 
    """
    a - список
    n - на сколько сдвигать
    """
    
    b = simple_dup(a)
    
    while n: 
        b = [b[-1]] + b[:-1]
        n -= 1
    
    return b


a = [1, 2, 3, 4, 5, 6]
print a
print "<< 2", left_move(a, 2)
print ">> 2", right_move(a, 3)


Автор: Void 24.1.2007, 18:07
V.A.KeRneL, в таком случае надо брать либо другой язык, либо другие задачи. Впрочем, самые ранние стадии обучения программированию для меня всегда были загадкой smile

Произвольный сдвиг можно и попроще записать.
Код
def shift(a, n):
    return a[n:] + a[:n]

n положительно — влево, отрицательно — вправо. Впрочем, чтобы не запоминать, я пошёл бы небольшое дублирование и оставил shift_left, shift_right с идентичным кодом.

Автор: Paranorma 25.1.2007, 23:09
Народ! тут такая проблемка...
Короче, вот как мне записать это задание:

Код

a = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(a) / 2:
    t = a[i]
    a[i] = a[-i - 1]
    a[-i - 1] = t
    i = i + 1
print a


без отрицательных индексов. То есть без -i
Я знаю, что например a[-1] это то же самое, что и a[len(a)-1]. И то и другое в квадратных скобках означает последний элемент списка. Я в силу своей неопытности решила, что можно записать так.


Код

a = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(a) / 2:
    t = a[i]
    a[i] = a[(len(a) - 1)  - 1]
    a[(len(a) - 1) - 1] = t
    i = i + 1
print a


Но не работает ведь! HELP!!!


Автор: V.A.KeRneL 25.1.2007, 23:34
Цитата(Paranorma @  25.1.2007, 23:09 Найти цитируемый пост)

Код

a = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(a) / 2:
    t = a[i]
    a[i] = a[(len(a) - 1)  - 1]
    a[(len(a) - 1) - 1] = t
    i = i + 1
print a


Paranorma, ``(len(a) - 1)  - 1'' — это ж константное выражение, равное ``len(a) - 2''! smile

Я думаю, после этого замечания ты и сама сможешь додуматься как надо. По крайней мере, взяв в руки листочек с карандашиком... smile
Но на всякий пожарный, как говорится, вотЬ: 
Код

a = [1, 2, 3, 4, 5, 6]
i = 0
while (i < len(a)/2): 
    t = a[i]
    a[i] = a[(len(a) - 1) - i]
    a[(len(a) - 1) - i] = t
    i += 1  # i = i + 1
print a


З.Ы. 
    i += 1  # Почему ты боишься использовать такую форму? 
            # Она очень удобна. 
            # Да, на самом деле, и проста в понимании. 
            # Она дословно означает: «увеличить значение переменной i на единицу». 
            # И писать меньше, и с точки зрения человеческой логики 1 команда вместо 2-х 
            # («сложить i c единицей» и «присвоить переменной i вычесленное значение»).

Автор: Paranorma 26.1.2007, 00:28
[QUOTE=V.A.KeRneL,25.1.2007,  23:34]
Цитата(Paranorma @  25.1.2007, 23:09 Найти цитируемый пост)

З.Ы. 
    i += 1  # Почему ты боишься использовать такую форму? 
            # Она очень удобна. 
            # Да, на самом деле, и проста в понимании. 
            # Она дословно означает: «увеличить значение переменной i на единицу». 
            # И писать меньше, и с точки зрения человеческой логики 1 команда вместо 2-х 
            # («сложить i c единицей» и «присвоить переменной i вычесленное значение»).

Я не боюсь, по мне эта форма тоже проста и понятна, но препод ругает за ее использование. smile 

Автор: Void 26.1.2007, 00:38
Цитата(Paranorma @  26.1.2007,  02:28 Найти цитируемый пост)
но препод ругает за ее использование

А подать сюда Ляпкина-Тяп… err… Странный у вас препод. Ума не приложу, какое может быть этому обоснование.

Автор: pythonwin 26.1.2007, 08:59
Цитата(Paranorma @  26.1.2007,  03:28 Найти цитируемый пост)
Я не боюсь, по мне эта форма тоже проста и понятна, но препод ругает за ее использование. smile  

а ты напиши преподавателю пример с длинными переменными - символов так 10 и более 

Автор: Artemios 26.1.2007, 11:27
Цитата(Paranorma @  26.1.2007,  00:28 Найти цитируемый пост)
Я не боюсь, по мне эта форма тоже проста и понятна, но препод ругает за ее использование. 

Мда... Бывает smile А какую он аргументацию приводит? На Паскаль не похоже? smile

Автор: pythonwin 26.1.2007, 11:33
Цитата(Artemios @  26.1.2007,  14:27 Найти цитируемый пост)
Мда... Бывает smile А какую он аргументацию приводит? На Паскаль не похоже? smile 

в Паскале для этого есть dec и inc

Автор: Karadul 6.2.2010, 09:49
V.A.KeRneL, оно может и покрасивше, но у тебя в каждой итерации выделяется память, или нет?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)