Используя массивы с другими массивами в Python

Попытка найти эффективный способ извлечь все экземпляры объектов в массиве из другого.

Например,

array1 = ["abc", "def", "ghi", "jkl"]

array2 = ["abc", "ghi", "456", "789"]

Массив 1 является массивом объектов, которые должны быть извлечены из массива 2. Таким образом выстройте 2, должен быть изменен к ["456", "789"]

Я знаю, как сделать это, но не эффективным способом.

5
задан Anthony Forloney 24 April 2010 в 22:56
поделиться

3 ответа

Это списки, а не массивы. (Слово «массив» означает разные вещи для разных людей, но в python объекты называют себя списками, и это все; есть другие модули, которые предоставляют объекты, которые называют себя массивами, например array и ] numpy )

Чтобы ответить на ваш вопрос, самый простой способ - вообще не изменять array2. Используйте понимание списка:

set1 = set(array1)
array2 = [e for e in array2 if e not in set1]

(набор делает это O (n) вместо O (n ^ 2))

Если вы абсолютно должны изменить array2 (потому что он существует в другом месте), вы можете использовать присвоение срезов:

array2[:] =  [e for e in array2 if e not in set1]

Это так же эффективно, но немного неприятно.

edit : как указывает Марк Байерс, это работает, только если array1 содержит только хешируемые элементы (такие как строки, числа и т. Д.).

6
ответ дан 14 December 2019 в 01:04
поделиться

Если ваши списки не могут содержать дубликатов и вам не важен порядок, тогда вам следует использовать наборы вместо списков (кстати, они называются списками, а не массивами). Тогда то, что вам нужно, будет быстро и тривиально реализовать:

>>> set1 = set(["abc", "def", "ghi", "jkl"])
>>> set2 = set(["abc", "ghi", "456", "789"])
>>> set2 - set1
set(['456', '789'])

Если list2 может содержать дубликаты или порядок имеет значение, вы все равно можете сделать list1 набором для ускорения поиска:

>>> list1 = ["abc", "def", "ghi", "jkl"]
>>> list2 = ["abc", "ghi", "456", "789"]
>>> set1 = set(list1)
>>> [a for a in list2 if a not in set1]
['456', '789']

Обратите внимание, что для этого требуется, чтобы элементы были хешируемыми. но работает почти за время O (n).

Если элементы нельзя хэшировать, но их можно заказать, вы можете отсортировать list1 и использовать двоичный поиск для поиска элементов в нем. Это дает время O (n log (n)).

Если ваши элементы не являются ни хешируемыми, ни упорядочиваемыми, тогда вам нужно будет прибегнуть к медленному O (n * n) простому линейному поиску для каждого элемента.

3
ответ дан 14 December 2019 в 01:04
поделиться

Простой способ выглядит примерно так:

array2 = [i for i in array2 if i not in array1]

понимание списков - вот что вам нужно здесь

0
ответ дан 14 December 2019 в 01:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: