Python: регулярное выражение с необработанной f-строкой работает только 50% времени - PullRequest
1 голос
/ 07 января 2020

У меня есть словарь кодов валют, каждый с набором кодов стран. Я хочу найти валюту конкретной страны с помощью Regex, поэтому я начал писать шаблон, но тот, который у меня есть на данный момент, работает только в 50% случаев. Это ошибка в Python?

Это код. Обязательно запустите его не менее пяти-десяти раз, чтобы убедиться, что оно работает только время от времени.

local_currencies = str({
    'GBP': {'UK'},
    'USD': {'US'},
    'EUR': {'FR', 'DE', 'IT'},
})

country = 'FR'
pattern = fr"'.{{3}}': ?\{{'{country}'"

print(re.search(pattern, local_currencies))

Ответы [ 3 ]

5 голосов
/ 07 января 2020

Причина этого сбоя заключается в том, что {'FR', 'DE', 'IT'} является set, а наборы не имеют определенного порядка. Когда это удается, это потому, что «FR» появился первым в строковом представлении. Когда это терпит неудачу, это потому, что «DE» или «IT» пришли первыми. Это не ошибка в Python. Вы не можете ожидать последовательного заказа из неупорядоченной коллекции.

Я настоятельно рекомендую использовать другой подход. Очень плохо полагаться на строковое представление python объектов. Вместо этого вы можете создать обратное отображение, например country_to_currency = {'FR': 'EUR', 'DE': 'EUR', 'US': 'USD'}. Затем вы можете просто сделать country_to_currency['FR'].

1 голос
/ 07 января 2020

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

Сохраните структуру данных и получите к ней прямой доступ. Учитывая это dict с вложенными set s:

local_currencies = {
    'GBP': {'UK'},
    'USD': {'US'},
    'EUR': {'FR', 'DE', 'IT'},
}

, легко ответить на вопрос типа «Какие валюты используются в стране X?» с пониманием списка:

country = 'FR'
currencies = [curr for curr in local_currencies if country in local_currencies[curr]]

Результат:

['EUR']

Для стран с несколькими валютами список будет длиннее.

0 голосов
/ 08 января 2020

Альтернативный подход заключается в том, чтобы инвертировать наборы, чтобы они были диктом стран и их валют:

local_currencies = {
    'GBP': {'UK'},
    'USD': {'US'},
    'EUR': {'FR', 'DE', 'IT'},
}

invert={}
for k, se in local_currencies.items():
    for e in se:
        invert[e]=k

>>> invert
{'UK': 'GBP', 'US': 'USD', 'IT': 'EUR', 'DE': 'EUR', 'FR': 'EUR'}
>>> invert['FR']
'EUR'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...