Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 1, 2015 12:35:02

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Есть массив из массивов, вложенные массивы одинаковой длины.
Отбираем из них с помощью random какое-то количество элементов и пытаемся получить последний элемент и все, кроме последнего. Очевидное решение - метод pop:

 import random
my_data = [[a,b,c] for a in range (10) for b in range (10)
           for c in ('q','w','e','r','t','y','u','i','o')]
for i in range(20):
    ts = random.sample(my_data, 20)
    for a in ts:
        ans = a.pop()
        print (a, 'last:', ans) 
В ответах проскакивают строки, где pop возвращает не букву, как должен, а цифру, т.е. вложенный массив с данными передается обрезанным:
[7, 3] last: u
[4, 9] last: i
[3] last: 1
[2] last: 3
[2, 0] last: r
[7, 1] last: q
[9, 4] last: t
[2] last: 2
[0, 4] last: i
[4, 2] last: o
[3] last: 5
[5, 7] last: e
А теперь меняем код. Вместо pop вернем по индексу последний объект и извлечем срез.
import random
my_data = [[a,b,c] for a in range (10) for b in range (10)
           for c in ('q','w','e','r','t','y','u','i','o')]
for i in range(20):
    ts = random.sample(my_data, 20)
    for a in ts:
        ans = a[-1]
        print (a[:-1], 'last:', ans)  
Вуаля! Все работает.
Почему так?

ЗЫ: если убрать рандомную выборку и с помощью pop извлекать элементы прямо из my_data , то все опять-таки работает корректно. Проблема возникает именно при совместной работе random.sample и pop.

Отредактировано Elaphe (Дек. 1, 2015 12:35:55)

Офлайн

#2 Дек. 1, 2015 12:54:29

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Уже объяснили. Не стоит забывать про разделяемые ссылки и изменяемые объекты

Отредактировано Elaphe (Дек. 1, 2015 12:56:22)

Офлайн

#3 Дек. 1, 2015 13:12:03

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Elaphe
Не стоит забывать про разделяемые ссылки и изменяемые объекты
Дело не в изменяемых объектах, а в том, что pop() удаляет элемент из списка и возвращает этот удалённый элемент. А sample() при повторных вызовах может выбирать из основного массива элементы, которые ранее уже выбирались.

>>> lst = [1, 2, 3]
>>> lst
[1, 2, 3]
>>> lst.pop()
3
>>> lst
[1, 2]
>>>



Отредактировано py.user.next (Дек. 1, 2015 13:16:15)

Офлайн

#4 Дек. 1, 2015 23:13:04

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Именно это и имелось в виду. Метод pop не создает копию, а изменяет сам массив, что невозможно было бы сделать с неизменяемым объектом.

Офлайн

#5 Дек. 1, 2015 23:36:25

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Elaphe
что невозможно было бы сделать с неизменяемым объектом
У неизменяемых объектов нет метода pop().



Офлайн

#6 Дек. 2, 2015 09:25:11

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Странно работают вместе random.sample и метод pop

Я в курсе.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version