Доступ к значению zip-объекта с использованием его индекса

#python

#python

Вопрос:

Я пытаюсь понять, как получить доступ к zip-объекту, и я пытаюсь выяснить, как получить доступ к значению в заархивированном объекте, используя индекс, используя .index() так же, как мы это делали раньше в Python 2.x, но, похоже, это не работает в Python3

Вот код

 def find_neighbors(index):
    i, j = index
    print([(i   1, j), (i - 1, j), (i, j   1), (i, j - 1)])
    return [(i   1, j), (i - 1, j), (i, j   1), (i, j - 1)]

list1 = (211,209,210,210)
list2 = (72,72,73,71)
points = zip(list1,list2)

for i, index in enumerate(points):
    for x in find_neighbors(index):
          if x is not in points: continue
          j = points.index(x)
  

Когда я запускаю код, я получаю эту ошибку: AttributeError: объект ‘zip’ не имеет атрибута ‘index’

Есть ли новый способ выполнения этого же механизма

Ответ №1:

Похоже, вы ожидаете points , что это будет список, но zip объекты не являются списками.

Если вы хотите преобразовать его в список, сделайте это:

 points = list(zip(list1,list2))
  

Комментарии:

1. когда я его преобразовал, теперь я получаю ValueError: (211, 72) отсутствует в списке, хотя у меня есть значение (211,72) для заархивированного объекта .. ?? Есть идеи

2. Вы уверены, что это ваш реальный код? Он содержит синтаксическую ошибку if x is not in , но после исправления я не получаю описанную вами ошибку.

Ответ №2:

zip используется для возврата списка в Python 2, но теперь является генератором в Python 3, поэтому вам придется сначала преобразовать его в список с помощью list конструктора, прежде чем вы сможете использовать index метод:

 points = list(zip(list1,list2))
  

Ответ №3:

Как говорят другие: zip возвращает zip-объект, который является итератором, который вы можете использовать для создания других вещей, таких как список или словарь. Кроме того, (a,b,c) возвращает кортеж, тогда как [a,b,c] возвращает список.

 >>> type((1,2,3))
<class 'tuple'>
>>> type([1,2,3])
<class 'list'>
>>> 
  

Для вас это может не иметь значения, если вы не хотите начать изменять содержимое «списков». Вы назвали их «списками», поэтому я сделал их списками ниже. В любом случае, как только вы заархивируете их и преобразуете в list ( list(zip(list1,list2) ), вы получите список кортежей. На самом деле это немного упрощает ваш код, потому что вы можете передать кортеж в свою функцию:

 def find_neighbors(point):
i = point[0]
j = point[1]
print(f"List of neighbours of {point}: {[(i   1, j), (i - 1, j), (i, j   1), (i, j - 1)]}")
return [(i   1, j), (i - 1, j), (i, j   1), (i, j - 1)]

list1 = [211,209,210,210,211]
list2 = [72,72,73,71,73]
pointsList = list(zip(list1,list2))

#These loops are just to show what is going on comment them out or delete them
for i in pointsList:
    print(i)
    print(f"The first element is {i[0]} and the second is {i[1]}")

#or let Python unpack the tuples - it depends what you want
for i, j in pointsList:
    print(i,j)

for point in pointsList:
print(f"In the loop for find_neighbours of: {point}")
for testPoint in find_neighbors(point):
    print(f"Testing {testPoint}")
    if testPoint not in pointsList:
        print(f"Point {testPoint} is not there.")
        continue
    elif testPoint in pointsList:
        print(f"*******************Point {testPoint} is there.***************************")
  

Обратите внимание, что я добавил к вашим данным точку, которая является соседней, чтобы мы могли видеть, как функция ее находит. Подумайте о разнице между списками и кортежами, прежде чем выполнять слишком много работы с тем или иным маршрутом. Мой код написан на Python 3.7.

Наконец, помните, что вы могли бы использовать словарь pointDict = dict(zip(list1,list2)) , который может быть более полезным для вас в вашей программе, особенно если вам нужно что-то посмотреть. Это может быть более питоническим.