как разделить число и строку в адресе - PullRequest
0 голосов
/ 28 мая 2020

у меня есть код для форматирования адреса

def format_address(address_string):
  house_number = ()
  street_name = ()

  address_string.split()

  for house_number, street_name in enumerate(address_string):
    if address_string[0].isnumeric():
      house_number = address_string

    elif address_string.isalpha():
      street_name = address_string


  return "house number {house_number} on street named {street_name}".format(house_number=house_number, street_name=street_name)

print(format_address("123 Main Street"))
print(format_address("1001 1st Ave"))
print(format_address("55 North Center Drive"))

результат желания должен быть:
номер дома 123 на улице с именем Main Street

мой результат: номер дома 123 Main Street на улица с названием t

чего мне здесь не хватает. Пожалуйста, помогите

Ответы [ 4 ]

1 голос
/ 28 мая 2020

Думаю, это то, чего вы пытаетесь достичь:

def format_address(address_string):

    house_number, street_name = address_string.split(' ', 1)

    return f"house number {house_number} on street named {street_name}"

print(format_address("123 Main Street"))
print(format_address("1001 1st Ave"))
print(format_address("55 North Center Drive"))

Вывод:

house number 123 on street named Main Street
house number 1001 on street named 1st Ave
house number 55 on street named North Center Drive
0 голосов
/ 28 мая 2020

Вы можете использовать регулярное выражение для захвата 3 частей.

'^([0-9]*)(.*)({"|".join(way)})[.]?$'

Это простое выражение делает свое дело. Каждая часть, содержащаяся в скобках, будет возвращена как группа в соответствии с регулярным выражением. У вас есть 3 части, поэтому я сделал 3 группы. Третья группа состоит из массива «всех возможных типов дорог» и их инициалов. Когда выполняется сопоставление, третья группа сравнивается с нашим списком, и с помощью модуля мы преобразуем номер совпадения, чтобы он соответствовал диапазону way_flat. Таким образом, независимо от того, какую версию вводит пользователь, мы всегда можем получить «полную» версию типа дороги. Это просто бонус. Вместо .. on street named Main Street вы получите .. on street named Main или, может быть, более иллюстративно ~ ..on boulevard named Fairbanks Manor.

Пример

import re
from typing import Pattern

way_flat = ('street', 'road', 'highway', 'parkway', 'avenue', 'boulevard')
way_init = ('st', 'rd', 'hwy', 'pkwy', 'ave', 'blvd')
way      = [*way_flat, *way_init]
way_len  = len(way_flat)

addr_filter: Pattern = re.compile(f'^([0-9]*)(.*)({"|".join(way)})[.]?$', re.I | re.M)

def format_address(addr: str) -> str:
    if m := addr_filter.match(addr):
        w = m.group(3).lower()
        for i, n in enumerate(way):
            if w == n:
                return f'House number {m.group(1)} on {way_flat[i%way_len]} named {m.group(2).strip()}'
        # fallback
        return f'House number {m.group(1)} on {w} named {m.group(2).strip()}'

    raise ValueError(f'Not An Address: {addr} is not a valid address')
        
try:
    print(format_address('123 Main St'))
    print(format_address('1 Fairbanks Manor Blvd'))
    print(format_address('8544 Onda highway'))
except ValueError as err:
    #do something
    pass

#House number 123 on street named Main
#House number 1 on boulevard named Fairbanks Manor
#House number 8544 on highway named Onda
0 голосов
/ 28 мая 2020

Как говорит Карл в своем ответе Чтобы решить проблему, вы должны ясно мыслить.

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

разделил строку на "" (пробел) и первым элементом был номер, остаток обозначен Тогда элемент * - это список с именем street_name_as_list. street_name объединяет все слова в этом списке с пробелами

def format_address(address_string):
  house_number = ()
  street_name = ()

  house_number, *street_name_as_list = address_string.split(" ")
  street_name = " ".join(street_name_as_list)

  return "house number {house_number} on street named {street_name}".format(house_number=house_number, street_name=street_name)

print(format_address("123 Main Street"))
print(format_address("1001 1st Ave"))
print(format_address("55 North Center Drive"))

, тогда вы можете добавить любые проверки для house_number или street_name, и нет необходимости использовать al oop в строке.

0 голосов
/ 28 мая 2020
address_string.split()

Это означает: создать новый список со словами из address_string, а затем игнорировать его . address_string равно без изменений . Вам нужно дать результат этого .split() называть его собственным именем. Точно так же, как если вы напишете 3 + 4, значение 3 не изменится, и полученное 7 будет полезно, только если вы сделаете с ним что-то .

for house_number, street_name in enumerate(address_string):

Это означает: каждый раз, проходя через l oop, house_number становится числом , начиная с нуля и считая вверх , а street_name становится следующей буквой в address_string (потому что мы все еще работаем с исходной строкой).

if address_string[0].isnumeric():
    house_number = address_string

Это означает: каждый раз через l oop, house_number будет заменяться на целиком address_string, если первый символ в address_string - это число c. address_string никогда не меняется, поэтому это сравнение всегда дает один и тот же результат. Строка типа "123 Main Street" начинается с "1", что является числовым значением c, поэтому house_number становится всей строкой "123 Main Street".

Каждый раз через l oop, house_number заменяется условием for l oop, а затем снова в этом if. В общем, вы не хотите присваивать переменные l oop; это не очень полезно, так как они будут повторно назначаться l oop.

elif address_string.isalpha():
  street_name = address_string

Так как условие if выполняется, этот elif никогда не тестируется.


Чтобы решить проблему, нужно ясно мыслить. Что вы хотите повторить? Какое хорошее имя использовать для этих вещей? Какое правило говорит вам, следует ли использовать эту вещь для house_number? Какое правило говорит вам, следует ли использовать эту штуку для address_string? Затем убедитесь, что используемые вами тесты имеют смысл - вы проверяете значение, которое действительно хотите использовать? Вы назначаете его в нужном месте?

...