Поиск идентификатора из больших списков быстрее в Python 2.7? - PullRequest
0 голосов
/ 12 декабря 2018

Итак, у меня есть два списка:

image_names = ["IMG_1.jpg", "IMG_2.jpg"]
data = [{"name": "IMG_1.jpg", "id": "53567"},
        {"name": "IMG_2.jpg", "id": "53568"},
        {"name": "IMG_3.jpg", "id": "53569"},
        {"name": "IMG_4.jpg", "id": "53570"}]

Я хочу найти первый элемент, затем следующий и т. Д. В images_names в данных, и если он имеет то же имя, чтобы получить идентификатор идобавьте его в список.

Вот как я это делаю:

for image_name in image_names:
    for datum in data:
        datum_name = datum.get("name", None)
        if datum_name == image_name:
           images_ids.append(datum.get("id", None))

Сейчас это прекрасно работает, но я думаю, что это действительно неэффективно, когда я получаю много данных вimages_names и данные.Какой лучший способ сделать это в Python?Я использую Python 2.7

Ответы [ 6 ]

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

Здесь нет необходимости в 2 циклах.Вы можете выполнить итерацию первого цикла и выполнить поиск имени изображения во втором списке, если совпадения добавляют идентификатор к идентификаторам изображений.Как ниже

    for datum in data:
          datum_name = datum.get("name", None)
          if any(datum_name in s for s in image_names):
                 images_ids.append(datum.get("id", None))
0 голосов
/ 12 декабря 2018

Другая опция:

[ item["id"] for item in data if item["name"] in image_names]
#=> ['53567', '53568']

Работает также, когда изображения с одинаковыми именами существуют с разными идентификаторами :

data = [{"name": "IMG_1.jpg", "id": "53500"},{"name": "IMG_1.jpg", "id": "53501"}]
#=> ['53500', '53501']
0 голосов
/ 12 декабря 2018

Используя списки и фильтры, вы можете попробовать это.Это работает с вашими существующими данными, хотя я настоятельно рекомендую вам реструктурировать ваш словарь в соответствии с рекомендациями других -

images_ids = [datum.get("id", None) for datum in data for image_name in 
image_names if datum.get("name", None) == image_name ]
0 голосов
/ 12 декабря 2018

Основная проблема заключается в том, что ваша структура данных не настроена для предоставления вам необходимого вам доступа.Вместо списка диктов сделайте этот естественный диктат, который вы хотите использовать:

data = {"IMG_1.jpg": "53567",
        "IMG_2.jpg": "53568",
        "IMG_3.jpg": "53569",
        "IMG_4.jpg": "53570"}

Теперь все, что вам нужно для создания списка id s, это

images_ids = [data[img] for img in image_names]

Если вам нужны оба метода доступа (если вам все еще нужны метки name и id), то я рекомендую вам научиться использовать фрейм данных Pandas с name и id в качествеколонны.Это даст вам лучшее из обоих методов.

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

Вы правы, это неэффективно.Вместо использования списка словарей, вы должны использовать словарь словарей или словарь объектов:

data = {"IMG_1.jpg": {"id": "53567"},
    "IMG_2.jpg": {"id": "53568"},
    "IMG_3.jpg": {"id": "53569"},
    "IMG_4.jpg": {"id": "53570"}}

for image_name in image_names:
    if (image_name in data):
        image_ids.append(data[image_name]["id"])

Вместо O (n) для поиска в списке вы получите O (1).) для поиска в словаре.

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

class ImageData:

    def __init__(self, name, id):
        self.Name = name
        self.Id = id

data = {"IMG_1.jpg": ImageData("IMG_1.jpg", "53567"),
    "IMG_2.jpg": ImageData("IMG_2.jpg", "53568"),
    "IMG_3.jpg": ImageData("IMG_3.jpg", "53569"),
    "IMG_4.jpg": ImageData("IMG_4.jpg", "53570")}

for image_name in image_names:
    if (image_name in data):
        image_ids.append(data[image_name].Id)
0 голосов
/ 12 декабря 2018
>>> images_ids = [filter(lambda x: x['name'] == name, data) for name in image_names]
>>> images_ids = [i[0]['id'] for i in images_ids if i]
>>> images_ids
['53567', '53568']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...