Из словаря ключей разделить на два ключа и значения в python, если регулярное выражение истинно

Я пытался сделать некоторые веб-скрапинг, когда обнаружил следующую проблему:

Это вложенные словари, полученные по ссылкам, которые я искал:

d1 = {'Gaia Project': {'Jugadores': '1 a 4', 'Duración': '60 – 150 minutos', 'Edad': '12+', 'Dureza': '4.37', 'Precio': '59,46€', 'Género': 'Eurogame – Mayorías', 'Editorial': 'Maldito Games', 'Diseñador/a': 'Jens Drögemüller', 'Total': '8.5', 'Aspecto / Componentes': '8', 'Diversión': '8', 'Variabilidad': '9.5', 'Originalidad': '9', 'Mecánicas': '8.5', 'Nota de lectores10 Votos': '8.5'}}
d2 = {'Churchill': {'Jugadores': '1 a 3', 'Duración': '60 – 300 minutos', 'Edad': '14+', 'Dureza': '3.28', 'Precio': '71,96€', 'Género': 'Eurogame – Construcción de Rutas, Económico.', 'Editorial': 'GMT Games\xa0/\xa0Devir', 'Diseñador/a': 'Mark Herman', 'Total': '8.9', 'Aspecto / Componentes': '8.1', 'Interacción': '9.7', 'Variabilidad': '8', 'Originalidad': '8.7', 'Mecánicas': '9.2'}}

Как вы можете видеть в d1, последняя категория упоминает:

'Nota de lectores10 Votos': '8.5'

Я хотел бы разделить на два ключа и значения, поэтому dict будет таким (см. конец):

{'Gaia Project': {'Jugadores': '1 a 4', 'Duración': '60 – 150 minutos', 'Edad': '12+', Dureza': '4.37', 'Precio': '59,46€', 'Género': 'Eurogame – Mayorías', 'Editorial': 'Maldito Games', 'Diseñador/a': 'Jens Drögemüller', 'Total': '8.5', 'Aspecto / Componentes': '8', 'Diversión': '8', 'Variabilidad': '9.5', 'Originalidad': '9', 'Mecánicas': '8.5', 'Nota de lectores': '8.5', 'N. Votes: 10 Votos'}}

Вот что я пробовал:

pattern_votes= r' de lectores\d.*'
if key.startswith('Nota'): 
            lectores = category.split(pattern_votes)
            category.append(lectores[0],"N. Votes")
            value.append(lectores[1])

Где категория будет 'N. Голосов» и ценность «10 голосов».

Я также пробовал if(filter(pattern_votes,d1)), но ничего не произошло.

Это списки из категории и значения соответственно:

category = ['Jugadores', 'Duración', 'Edad', 'Dureza', 'Precio', 'Género', 'Editorial', 'Diseñador/a', 'Total', 'Aspecto / Componentes', 'Diversión', 'Variabilidad', 'Originalidad', 'Mecánicas', 'Nota de lectores10 Votos']

value = ['1 a 4', '60 – 150 minutos', '12+', '4.37', '59,46€', 'Eurogame – Mayorías', 'Maldito Games', 'Jens Drögemüller', '8.5', '8', '8', '9.5', '9', '8.5', '8.5']

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ Как предложил Кулдип, вот мой код:

В конце концов, строка - это то, что я пробовал, но не работал.


import requests
import re
from bs4 import BeautifulSoup
import os
from collections import defaultdict


link = "https://mishigeek.com/gaia-project-resena-en-solitario/"
link2 = "https://mishigeek.com/churchill-resena-en-espanol-es-un-wargame/"
#def get_ratings(review):   
# Capturo la cabecera de la petición HTTP

def get_info(link):
    headers = requests.utils.default_headers()


    headers.update(
        {
             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36',
         }
     )

    # Me conecto a la url con .get()
    sitemap_soup = requests.get(link, headers=headers)
    sitemap_soup.close()
    if (sitemap_soup.ok==True):
        
        soup = BeautifulSoup(sitemap_soup.text,features="html.parser")
        d= defaultdict(dict)
        key=[]   
        category=[]
        value=[]
        otros=[] # Other set of category and values that will have to split.
        pattern = r'-resena.*$'
        pattern_votes= r' de lectores\d.*'
        
        
        # Mediante los bucle for, se buscan todos los valores que coincida con el soup.select
        for each_part in soup.select('figure[class*="wp-block-table"]'):
            for each_part in soup.select('tr'):
                otros.append(each_part.get_text())
        split_items = (i.split(':') for i in otros[:8])
        category, value = zip(*split_items)
        category, value = map(list, (category, value))
        
        nombre = re.sub(pattern,'',os.path.basename(link[:-1])).replace('-', ' ').title()
        key.append(nombre)
        category.append("Total")
        
        for each_part in soup.select('div[class*="lets-review-block lets-review-block__final-score"]'):
                value.append(each_part.get_text())
                 
        for each_part in soup.select('div[class*="lets-review-block__crit__title lr-font-h"]'):
                category.append(each_part.get_text())
               
        for each_part in soup.select('div[class*="lets-review-block__crit__score"]'):
                value.append(each_part.get_text())
                
        for k in key:
           for c,v in zip(category,value):
               d[k][c]=v
        
        
            
        print(d)
        print(category)
        print(value)
        '''
        if key.startswith('Nota'): 
            lectores = category.split(pattern_votes)
            category.append(lectores[0],"N. Votos")
            value.append(lectores[1])
        '''

Пожалуйста, рассмотрите возможность пересмотра примера кода, который вы разместили в этом вопросе. В его нынешнем виде из-за его форматирования и объема нам сложно вам помочь; вот отличный ресурс, чтобы вы начали с этого. -1, не пойми неправильно. Голосование против — это то, как мы указываем здесь проблему с контентом; улучшите форматирование и образец кода, и я (или кто-то другой) с радостью верну его. Удачи с кодом!

Kuldeep Singh Sidhu 09.04.2022 13:40

Привет, Кулдип, я только что опубликовал свой код, как вы упомянули. Благодарю вас!

Ignacio Such 09.04.2022 13:53
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
2
44
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Какие наши действия:

  1. Перебирать все фильмы и их свойства
  2. Найти свойство с определенным именем
  3. Извлечь количество голосов
  4. Обновить свойства

Давайте реализуем это:

import re

pattern = r"Nota de lectores(\d+).*" # our pattern to match full key and extract number of votes

for movie, properties in movies.items(): # 1
    m = None
    for k, v in properties.items():
        if m := re.match(pattern, k): # 2, this syntax assumes python 3.8
            break
    if m is not None:
        # 4
        del properties[m.group(0)] # remove old key
        properties["Nota de lectores"] = v # store previous value
        properties["Votes"] = m.group(1) # 3

Обратите внимание, что мы не можем обновлять свойства во время цикла, так как мы не можем изменить размер словаря во время итерации.

Ответ принят как подходящий

Начнем с самой маленькой проблемы: как разделить «Nota de lectores10 Votos» на «Nota de lectores» и «10 голосов». Мой подход заключается в использовании библиотеки itertools: используйте takewhile, чтобы получить часть до первой цифры, и dropwhile для части, начиная с первой цифры.

import itertools
def split_before_number(text):
    """Split text into 2 parts: before the first digit and the rest."""
    def not_digit(c):
        """Return True if character c is not a digit."""
        return not c.isdigit()
    before = ''.join(itertools.takewhile(not_digit, text))
    after = ''.join(itertools.dropwhile(not_digit, text))
    return before, after

Попробуй это:

>>> split_before_number('Nota de lectores10 Votos')
('Nota de lectores', '10 Votos')

Далее я хотел бы решить проблему преобразования пары ключ/значение в 1 или 2 пары:

# This pair 'Jugadores': '1 a 4'
# Becomes:  'Jugadores': '1 a 4'

# This pair: 'Nota de lectores10 Votos': '8.5'
# Becomes:   'Nota de lectores': '8.5'
# and        'N. Votes': '10 Votos'

Код для этого:

def split_key_and_value(key, value):
    if not key.startswith("Nota"):
        yield key, value
        return

    key1, value2 = split_before_number(key)
    yield key1, value
    yield "N. Votes", value2

Попробуй это:

>>> dict(split_key_and_value('Nota de lectores10 Votos', "8.5"))
{'Nota de lectores': '8.5', 'N. Votes': '10 Votos'}

>>> dict(split_key_and_value("Jugadores", "1 a 4"))
{'Jugadores': '1 a 4'}

С помощью этих функций мы теперь можем работать над более крупной проблемой: преобразованием ключей и значений значения d1, которое я называю v1:

def transform(dict_object):
    """Split some specific keys and values and form a new dict."""
    new_dict_object = {}
    for original_key, original_value in dict_object.items():
        for key, value in split_key_and_value(original_key, original_value):
            new_dict_object[key] = value
    return new_dict_object

Попробуй это:

>>> d1 = {'Gaia Project': {'Jugadores': '1 a 4',
  'Duración': '60 – 150 minutos',
  'Edad': '12+',
  'Dureza': '4.37',
  'Precio': '59,46€',
  'Género': 'Eurogame – Mayorías',
  'Editorial': 'Maldito Games',
  'Diseñador/a': 'Jens Drögemüller',
  'Total': '8.5',
  'Aspecto / Componentes': '8',
  'Diversión': '8',
  'Variabilidad': '9.5',
  'Originalidad': '9',
  'Mecánicas': '8.5',
  'Nota de lectores10 Votos': '8.5'}}

>>> v1 = d1["Gaia Project"]

>>> transform(v1)
{'Jugadores': '1 a 4',
 'Duración': '60 – 150 minutos',
 'Edad': '12+',
 'Dureza': '4.37',
 'Precio': '59,46€',
 'Género': 'Eurogame – Mayorías',
 'Editorial': 'Maldito Games',
 'Diseñador/a': 'Jens Drögemüller',
 'Total': '8.5',
 'Aspecto / Componentes': '8',
 'Diversión': '8',
 'Variabilidad': '9.5',
 'Originalidad': '9',
 'Mecánicas': '8.5',
 'Nota de lectores': '8.5',
 'N. Votes': '10 Votos'}

Теперь, когда мы можем преобразовать значение d1, мы можем применить это преобразование к d1:

>>> d1 = {key: transform(value) for key, value in d1.items()}

>>> d1
{'Gaia Project': {'Jugadores': '1 a 4',
  'Duración': '60 – 150 minutos',
  'Edad': '12+',
  'Dureza': '4.37',
  'Precio': '59,46€',
  'Género': 'Eurogame – Mayorías',
  'Editorial': 'Maldito Games',
  'Diseñador/a': 'Jens Drögemüller',
  'Total': '8.5',
  'Aspecto / Componentes': '8',
  'Diversión': '8',
  'Variabilidad': '9.5',
  'Originalidad': '9',
  'Mecánicas': '8.5',
  'Nota de lectores': '8.5',
  'N. Votes': '10 Votos'}}

Другие вопросы по теме

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

Как эффективно подсчитать все конкатенации двух кортежей в более длинные цепочки в Python
Как использовать «эксперта» на основе правил для имитационного обучения?
Python Как мне отфильтровать несколько строк из большой строки, а затем поместить ее в файл .txt
Как найти предыдущий элемент в упорядоченном словаре, который имеет просматриваемое значение
Изображения, созданные из набора данных, повернуты
Я новичок в питоне. Как обрезать изображение на основе радиуса объекта на картинке с помощью open.cv. Ниже мои несколько фотографий
Как подключить файл css в колбе?? Там в другом Syntex?
Webscraping - получить первое и второе значение из тега div с несколькими значениями, разделенными запятой
Как объединить элементы на основе одного и того же ключа/значения в списке Python
Как я могу изменить цвет фона на красный цвет изображения с помощью Python