Проблемы с областью действия для циклов в Python - PullRequest
0 голосов
/ 20 октября 2011

В следующем коде, когда я печатаю строку в первом цикле после выполнения множества манипуляций с ней, я вижу результаты, которые мне нужны.Однако после выхода из первого цикла я обнаружил, что получаю другой результат в переменной Dataset.Я знаю, что это ограниченная проблема, но я не могу понять, в чем проблема и как получить желаемый результат, который показан с первым оператором «print».Спасибо за вашу помощь

import random
random.seed(1234567)
Key=[[.5,.5]]
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2)

print "results I need"
for row in Dataset:
    response=row[0]
    for i in xrange(len(Key)):
        if random.random() < Key[i][response]: 
            row[i+1]=response
        else: 
            row[i+1]=1-response
    print row

print "Results I get"
for row in Dataset:
    print row

Ответы [ 4 ]

3 голосов
/ 20 октября 2011
  • Python имеет ссылочную семантику.Ваш оригинальный Dataset содержит несколько ссылок на общие подсписки [0, 0] и [1, 0].(Я также затрудняюсь понять, почему вы делаете инициализацию настолько сложной.)

Вы можете исправить это, используя [[0, 0] for i in xrange(5)] + [[1, 0] for i in xrange(5)].

  • .остальная часть вашей логики также излишне сложна.Мы можем использовать условное выражение для объединения двух назначений, и мы должны использовать прямую итерацию вместо того, чтобы перебирать искусственный список индексов (xrange).

Это выглядит так:*

for row in Dataset:
    response = row[0]
    for k in Key:
        row[i + 1] = response if random.random() < k[response] else 1 - response
  • Однако это все еще не решение, которое мы ищем.На самом деле нет причин помещать все эти нули в данные инициализации, которые будут перезаписаны и никогда не будут считываться в цикле.Индекс [i + 1] также неуклюж.Более простое решение: начните со списка только первых значений для подсписков, а внутри цикла создайте оставшуюся часть каждого подсписка (мы можем сделать это с помощью понимания списка) и добавьте первый элемент.Вместо замены элементов Dataset на месте, мы можем использовать другое понимание списка, чтобы связать их вместе.

Это дает нам:

import random
random.seed(1234567)
Key=[[.5,.5]]
Initial_Conditions=[0]*int(10/2) +[1]*int(10/2)

Dataset = [
    [i] + [
        i if random.random() < k[i] else 1 - i
        for k in Key
    ]
    for i in Initial_Conditions
]
2 голосов
/ 20 октября 2011

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

Dataset = [[0]+[0]*1 for x in range(10//2)] + [[1]+[0]*1 for x in range(10//2)]
0 голосов
/ 20 октября 2011

Это не проблема определения объема. Я думаю, что он хочет обновить набор данных,

см. Модифицированный скрипт ниже

import random
random.seed(1234567)
Key=[[.5,.5]]
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2)

print "results I need"
for row in range(len(Dataset)): # Changes
    response=Dataset[row][0]
    for i in xrange(len(Key)):
        if random.random() < Key[i][response]:
            Dataset[row][i+1]=response # Important
        else:
            Dataset[row][i+1]=1-response # Important
    print Dataset[row]

print "Results I get"
for row in Dataset:
    print row
0 голосов
/ 20 октября 2011

Проблема в том, как строится набор данных.Это содержимое не всех уникальных списков - некоторые из них являются тождественно одним и тем же объектом (а не одним и тем же содержимым)Это легко исправить:

Dataset=[[0,1] for i in range(10//2)] + [[1,0] for i in range(10//2)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...