2013-12-10 3 views
1

У меня проблема. В python у меня есть функция, которая должна печатать самый длинный путь. Функция работает, если я использую список как [[1,2,3,4,5][1,2,3,4,5]], но если я использую список, например, [x] for x in range(5)]*2 или любой другой список. (Я не знаю, что это называется в python, но если у меня есть список как [vale] * что-то), код не работает. Итак, мой вопрос: как я могу создать новый список без каких-либо ссылок. Deepcopy или [:] не работает, потому что ссылки внутри списка все еще существуют. Но я не знаю, как копировать только значения, без ссылок. :) Благодаря.Ввод питона в список

def naj_narascajoca(vrtek): 


    visina = len(vrtek) 
    sirina = len(vrtek[0]) 

    vrt = [] 
    vrt.append([-1]*(sirina+2)) 
    for greda in vrtek: 
     greda.insert(0,-1) 
     greda.append(-1) 
     vrt.append(greda) 

    vrt.append([-1]*(sirina+2)) 


    for i in vrt: 
     print(i) 


    pot = "" 
    maximal = 0 
    je_vecja = True 
    x = 1 
    y = 1 
    max_odlocitev = 0 
    while je_vecja == True: 

     print("--------------",vrt[x][y],"-----------------") 

     vre_left = vrt[x][y-1] 
     vre_right = vrt[x][y+1] 
     vre_up = vrt[x-1][y] 
     vre_down = vrt[x+1][y] 
     sez = sorted([vre_down,vre_left, vre_right, vre_up]) 
     for i in sez: 
      if i > maximal: 
       max_odlocitev = i; 
       break 
     #max_odlocitev = max(vrt[x][y-1],vrt[x][y+1], vrt[x+1][y], vrt[x-1][y]) 
     if maximal < max_odlocitev: 
       maximal = max_odlocitev 
       if vrt[x][y-1] == maximal: 
        pot += "L" 
        y -=1 
       elif vrt[x][y+1] == maximal: 
        pot += "R" 
        y+=1 
       elif vrt[x+1][y] == maximal: 
        pot += "D" 
        x+=1 
       elif vrt[x-1][y] == maximal: 
        pot += "U" 
        x-=1 


     else: 
      je_vecja = False 

    print(pot) 

vrt = [[1,3,3,8,5,4,2,1,5,6], 
    [2,4,3,3,6,8,1,3,5,6], 
    [4,5,6,4,7,4,3,6,4,7], 
    [2,8,7,0,0,7,4,7,8,0], 
    [2,3,4,7,0,8,7,6,3,8], 
    [3,7,9,0,8,5,3,2,3,4], 
    [1,5,7,7,6,4,2,3,5,6], 
    [0,6,3,3,6,8,0,6,7,7], 
    [0,1,3,2,8,0,0,0,0,0], 
    [3,1,0,3,6,7,0,5,3,1], 
    [1,3,5,7,0,8,6,5,3,1], 
    [3,6,3,1,3,5,8,7,5,1], 
    [4,3,6,0,0,8,4,7,5,3], 
    [3,5,6,8,6,3,1,3,5,2]] 

#naj_narascajoca(vrt) 
naj_narascajoca([[x] for x in range(5)]*2) 

ответ

1

Все так:

[any mutable objects] * 2 

... явно делает две ссылки на каждый изменяемый объект. Неважно, как вы создаете исходный список, это та же проблема, с тем же решением, которое описано в the FAQ: вам нужно определить список дважды. Таким образом, вместо этого:

[[x] for x in range(5)]*2 

... это сделать:

[[x] for _ in range(2) for x in range(5)] 

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

copy.deepcopy([[x] for x in range(5)]*2) 

И deepcopy умнее, чем вы думаете. Это делает глубокую копию вашей структуры из 2 ссылок на тот же список из 5 списков. Таким образом, вы получаете 5 новых списков, новый список из 5 списков и 2 новые ссылки на этот новый список.

Но это может делать то, что вы хотите. Вам просто нужно скопировать список перед тем положить две копии вместе:

>>> a = [[x] for x in range(5)] 
>>> b = [copy.deepcopy(a), copy.deepcopy(a)] 
>>> # or [copy.deepcopy(a) for _ in range(2)] 
>>> b[0] is b[1] 
False 
>>> b[0][0] is b[1][0] 
False 

или, альтернативно, карту копии по списку из двух ссылок, так что каждый из них копируются по отдельности:

>>> b = [copy.deepcopy(x) for x in a*2] 
>>> b[0][0] is b[1][0] 
False 
+0

Спасибо за это, но проблема в том, что я не знаю, какой тип списка я получу. Список может быть указан как '[любые изменяемые объекты] * 2' или, как' [[1,2,3,4] [1,2,2,2]] '... или что-нибудь еще. Итак, я хотел бы создать новый список, но скопировать только значения, а не ссылки. Это возможно? –

+0

Я не могу редактировать последний комментарий. Я добавлю еще несколько объяснений. И, если я получу список, назовем его 'abc', а abc [0] -' abc [1] 'Мне нужен новый список, например' defg [] ', который будет' defg [0] ' не 'defg [1]', а 'abc [0] == defg [0]' и тот же для '[1]'. Итак, те же значения, но не ссылки, даже во внутренних списках. –

+0

@MatejMohar: Кажется, я знаю, что вы имеете в виду. Позвольте мне отредактировать ответ. – abarnert

0

Когда вы используете *2 в списке, вы не делаете копии списка, как вы обнаружили, вы делаете две ссылки на один и тот же список. Вы можете использовать другой уровень понимания списка, чтобы получить то, что вам нужно.

[[[x] for x in range(5)] for y in range(2)] 

Или, возможно, проблема заключается в том, что вы получаете список списков во внутренней части, когда вы хотите только один список 1-5:

[list(range(1, 6)) for x in range(2)] 
+0

Понимание понятий не дает вам нужного списка; вы получите '[[[0], [1], [2], [3], [4]], [[0], [1], [2], [3], [4]]]' вместо из [[0], [1], [2], [3], [4], [0], [1], [2], [3], [4]]. Вам нужно одно вложенное понимание (как в моем ответе), если вы не хотите сгладить его после факта (например, 'list (chain.from_iterable (...))). – abarnert

+0

@abarnert, вот почему я представил второе решение, потому что думал, что, вероятно, ближе к тому, что было предназначено. –

+0

Привет! Спасибо за ответ. Я отвечаю на ответ @abarnet, так что, пожалуйста, взгляните :) –

Смежные вопросы