Внутренняя работа map() в конкретной ситуации синтаксического анализа

#python-3.x #string #parsing #integer

#python-3.x #строка #синтаксический анализ #целое число

Вопрос:

Я знаю, что уже есть по крайней мере две темы, которые объясняют, как map() это работает, но, похоже, я не могу понять, как это работает в конкретном случае, с которым я столкнулся.

Я работал над следующим упражнением на Python:

Напишите программу, которая вычисляет чистую сумму банковского счета на основе журнала транзакций из ввода с консоли. Формат журнала транзакций показан следующим образом:

 D 100
W 200
 

D означает депозит, в то время как W означает вывод средств. Предположим, что в программу вводятся следующие входные
данные:

 D 300
D 300
W 200
D 100
 

Затем результат должен быть:

 500
 

Один из ответов, предложенных для этого упражнения, был следующим:

 total = 0
while True:
    s = input().split()
    if not s:
        break
    cm,num = map(str,s)

    if cm=='D':
        total =int(num)
    if cm=='W':
        total-=int(num)

print(total)
 

Теперь я понимаю, что map применяет функцию (str) к итерациям, но чего я не вижу, так это того, как программа определяет, что является числом в s строке. Я предполагаю str , что преобразует каждую букву / число / etc в строковый тип, но тогда как int(num) узнать, что выбрать в качестве целого числа? Другими словами, почему этот код не выдает какой-либо ошибки типа или ошибки значения, потому что, как я это вижу, он попытался бы создать целое число (например) «D 100»?

Ответ №1:

Первый

 cm,num = map(str,s)
 

может быть упрощен следующим образом

 cm,num = s
 

since s — это уже список строк, состоящий из 2 элементов (если ввод правильный). Нет необходимости преобразовывать строки, которые уже являются строками. s просто распаковывается на 2 переменные.

насколько я понимаю, он попытался бы составить целое число из (например) «D 100»?

нет, это невозможно, поскольку num является вторым параметром строки.

если входные данные есть "D 100" , то s есть ['D','100'] , то cm есть 'D' и num есть '100'

Затем, поскольку num представляет целое int(num) число, оно будет преобразовано num в его целочисленное значение.

Приведенный выше код полностью лишен проверки ошибок (количество параметров, параметры «тип»), но с правильными параметрами он работает.

и map совершенно бесполезен в этом конкретном примере тоже.

Ответ №2:

Причина в .split() том, что оператор, приведенный ранее в s = input().split() . Это создает list значения D и 100 (или ['D', '100'] ), потому что символом разделения по умолчанию является пробел ( ) . Затем map функция применяет str операцию к обоим 'D' и '100' .

Теперь map функция , на самом деле не требуется, потому что оба значения при вводе автоматически имеют тип str (строки).

Второй вопрос заключается в том, как int(num) узнать, как преобразовать строку. Это связано со вторым (неявным) аргументом base . Аналогично тому, как .split() имеет аргумент символа по умолчанию для разделения, так и у num есть аргумент по умолчанию для преобразования.

Полный код похож на int(num, base=10) . Так что, пока num имеет значения 0-9 и не более 1 . , int может правильно преобразовать его в базовое значение 10. Для получения дополнительных примеров ознакомьтесь со встроенным int .