Python - как проверить / открыть список ссылок? - PullRequest
0 голосов
/ 09 декабря 2018

Одним из наиболее запутанных аспектов в python является создание списка списков (при условии, что вы не используете numpy) - например, если вы попытаетесь сделать это с помощью более простого умножения, вы получите справочные копии:

In [1]: a = [[0] * 4] * 4
In [2]: a
Out[2]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

In [3]: a[0][1] = 1
In [4]: a
Out[4]: [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]

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

In [5]: b = [[0 for i in range(4)] for i in range(4)]
In [6]: b         
Out[6]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

In [7]: b[0][1] = 1
In [8]: b                                           
Out[8]: [[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Вопрос заключается в следующем -Предположим, кто-то определил их список как со списком a, есть ли способ проверить массив таким образом, чтобы он показал, что он использует ссылки?Простая печать массива не будет раскрывать ссылки.

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Сначала немного терминологии: здесь речь идет о списках (а не массивах), которые всегда хранят ссылки на свои элементы.

Быстрый способ проверить, ссылаются ли все ссылки в списке на разные объекты, -

>>> l1 = [[0, 1], [0, 1]]
>>> l2 = [[0, 1]]*2
>>> 
>>> len(set(map(id, l1))) == len(l1) # no duplicates
True
>>> len(set(map(id, l2))) == len(l2) # duplicates
False

, который просто проверяет, есть ли n уникальные идентификаторы для объектов в списке длиной n.

Если в вашем списке очень большое количество элементов, это может бытьболее эффективно делать это лениво и возвращать False в первом дублированном идентификаторе.

def all_unique(lst):
    seen = set()
    for x in lst:
        id_ = id(x)
        if id_ in seen:
            return False
        seen.add(id_)
    return True

... работает так:

>>> all_unique(l1)
True
>>> all_unique(l2)
False
0 голосов
/ 09 декабря 2018

Вы можете использовать функцию id:

>>> a = [[0] * 4] * 4
>>> a
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> [id(sublist) for sublist in a]
[1975671202696, 1975671202696, 1975671202696, 1975671202696]
>>> b = [[0 for i in range(4)] for i in range(4)]
>>> b
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> [id(sublist) for sublist in b]
[1975671204808, 1975671205128, 1975671205000, 1975671204872]

Как видите, в a идентификаторы все одинаковые, а в b они разные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...