У меня есть функция в Python, которая вызывается функцией map (), выполняющей итерацию по всем элементам списка, которые отправляются как параметры. Эта функция возвращает словарь, а функция карты назначается словарю, но интерпретатор Python преобразует ее в список.

hotels_with_low_wifi_quality = pool.map(get_accomodation_wifi_rating, hotels_url_list)

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

Но если я напечатаю hotels_with_low_wifi_quality, он выведет следующее:

[None, None, None, None, None, None, None, None, None, {u '\ nPins Platja \ n': u'4,3 '}, None, None, None, None, None] None

Это явно список. Как преобразовать его в словарь, где значения None игнорируются, а единственным элементом является ["Pins Platja"] = 4.3

Ниже находится get_accomodation_wifi_rating

def get_accomodation_wifi_rating(hotel):
page = requests.get(hotel)
soup = BeautifulSoup(page.text, 'lxml')
hotel_name = soup.find(id = "hp_hotel_name").text
reviews = soup.find(class_="review_list_score_breakdown_right")
if reviews is not None:
    wifi_tag = reviews.find(attrs={"data-question" : "hotel_wifi"})
    if wifi_tag is not None:
        wifi_rating = wifi_tag.find(class_="review_score_value")
        wifi_score = wifi_rating.text
        wifi_score_num = wifi_score.replace(",", ".")
        if float(wifi_score_num) < 7:
            hotels_with_low_wifi_quality[hotel_name] = wifi_score
            return hotels_with_low_wifi_quality
1
Ian Spitz 1 Янв 2018 в 04:19

2 ответа

Лучший ответ

Похоже, вы хотите получить все низкие оценки Wi-Fi параллельно . Все правы в том, что использовать глобальный словарь - это действительно плохая идея . Есть менее подробный способ выполнить то, что вы хотите:

  1. Вернуть (кортеж), состоящий из (название отеля, счет) в вашем get_accomodation_wifi_rating функция:

    return (hotel_name, wifi_score)

  2. Используйте встроенный в python filter, чтобы отфильтровать ваши NoneTypes:

    hotels_with_low_wifi_quality = dict(filter(None, returned_list))

Приведенный выше фильтр без предоставленной функции оценивает каждый элемент в списке на основе оценки python истинности этого элемента; просто нужно иметь в виду.

3
bicelot3 1 Янв 2018 в 04:04

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

# We first map to get ratings
ratings = [get_accomodation_wifi_rating(name) for name in pool]

# We then filter the None out
ratings = [x for x in ratings if x is not None]

# We now have a list of `dict` which we want to merge
hotels_with_low_wifi_quality = {
    name: rating
        for d in ratings
        for name, rating in d.items()
}

Хотя я хочу отметить, что ваша функция get_accomodation_wifi_rating имеет возвращаемый тип, который неудобен для того, что вы хотите сделать.

Прежде всего, кажется, что он заполняет глобальный dict и возвращает его, что является действительно плохая идея.

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

hotels_with_low_wifi_quality = dict(
    x
    for x in [get_accomodation_wifi_rating(name) for name in pool]
    if x is not None
)
0
Olivier Melançon 1 Янв 2018 в 02:02