Использовать try catch с бесконечным циклом while. Чтобы проверить пустую строку, используйте инструкцию IF, чтобы проверить, является ли строка пустой.
while True:
name = input("Enter Your Name\n")
if not name:
print("I did not understood that")
continue
else:
break
while True:
try:
salary = float(input("whats ur salary\n"))
except ValueError:
print("I did not understood that")
continue
else:
break
while True:
try:
print("whats ur age?")
age = int(float(input()))
except ValueError:
print("I did not understood that")
continue
else:
break
print("Hello "+ name + "\nYour salary is " + str(salary) + '\nand you will be ' + str(age+1) +' in a Year')
Python пытается отговорить вас от «суммирования» строк. Вы должны присоединиться к ним:
"".join(list_of_strings)
Это намного быстрее и использует гораздо меньше памяти.
Быстрый тест:
$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = reduce(operator.add, strings)'
100 loops, best of 3: 8.46 msec per loop
$ python -m timeit -s 'import operator; strings = ["a"]*10000' 'r = "".join(strings)'
1000 loops, best of 3: 296 usec per loop
Edit (чтобы ответить на редактирование OP): Что касается того, почему строки были, по-видимому, «выделены», я считаю, что это просто вопрос оптимизации для общего случая, а также для обеспечения наилучшей практики: вы можете присоединяться к строкам намного быстрее с помощью ''. join, поэтому явно запрещающие строки на sum
укажут это на новичков.
Кстати, это ограничение было на месте «навсегда», т. е. поскольку sum
был добавлен как встроенный функция [ rev. 32347 )
Краткий ответ: Эффективность.
Длинный ответ: функция sum
должна создать объект для каждой частичной суммы.
Предположим, что время, необходимое для создания объект прямо пропорционален размеру его данных. Пусть N обозначает количество элементов в последовательности для суммирования.
double
s всегда одного размера, что делает время работы sum
O (1) × N = O (N) .
int
(ранее известное как long
) является произвольной длиной. Обозначим через M абсолютное значение наибольшего элемента последовательности. Тогда наихудшее время работы sum
: lg (M) + lg (2M) + lg (3M) + ... + lg (NM) = N × lg (M) + lg (N!) = O (N log N).
Для str
(где M = длина самой длинной строки) наихудшее время работы: M + 2M + 3M + ... + NM = M × (1 + 2 + ... + N) = O (N²).
Таким образом, строки sum
ming будут намного медленнее, чем sum
числа ming.
str.join
не выделяет никаких промежуточных объектов. Он предопределяет буфер, достаточно большой для хранения объединенных строк, и копирует строковые данные. Он работает в O (N) раз, намного быстрее, чем sum
.
sum
для строк, и не многие используют sum
для списков и кортежей. Ловушка заключается в том, что sum
отлично работает для коротких списков строк, но затем запускается в производство, где списки могут быть огромными, а производительность замедляется до обхода. Это была такая общая ловушка, что было принято решение игнорировать утиную печать в этом случае и не допускать использования строк с sum
.
– Ethan Furman
28 April 2014 в 21:01
Изменить: перемещение частей относительно неизменяемости в историю.
В принципе, это вопрос предварительного распределения. Когда вы используете инструкцию типа
sum(["a", "b", "c", ..., ])
и ожидаете, что она будет работать аналогично оператору reduce
, генерируемый код выглядит примерно как
v1 = "" + "a" # must allocate v1 and set its size to len("") + len("a")
v2 = v1 + "b" # must allocate v2 and set its size to len("a") + len("b")
...
res = v10000 + "$" # must allocate res and set its size to len(v9999) + len("$")
. В каждом из этих шаги создают новую строку, которая может дать некоторые накладные расходы на копирование, поскольку строки становятся длиннее и длиннее. Но, может быть, и не здесь. Более важно то, что каждая новая строка в каждой строке должна быть выделена для определенного размера (что. Я не знаю, что она должна выделяться на каждой итерации оператора reduce
, там может быть некоторые очевидные эвристики для использования, и Python может выделить немного больше здесь и там для повторного использования, но в нескольких точках новая строка будет достаточно большой, чтобы это больше не помогло, и Python должен снова выделить, что довольно дорого.
Специальный метод, подобный join
, однако имеет задачу выяснить реальный размер строки перед ее запуском и поэтому теоретически будет выделять только один раз в начале, а затем просто заполнить эту новую строку, которая намного дешевле другого решения.
"",join
ведет себя намного лучше, чем общая сумма. Мне пришлось посмотреть код , чтобы понять. Я думаю, что неизменность - это красная селедка.
– Muhammad Alkarouri
19 August 2010 в 21:22
Я не знаю почему, но это работает!
import operator
def sum_of_strings(list_of_strings):
return reduce(operator.add, list_of_strings)
reduce
не sum
, но он будет по-прежнему иметь ужасную производительность для больших списков.
– Ethan Furman
22 November 2014 в 02:36
Причина, по которой
@ dan04 имеет прекрасное объяснение затрат на использование sum
в больших списках строк.
Недостающий вопрос о том, почему str
не разрешено для sum
, состоит в том, что многие, многие люди пытались использовать sum
для строк, и не многие используют sum
для списков и кортежей и других структур данных O (n ** 2). Ловушка заключается в том, что sum
отлично работает для коротких списков строк, но затем запускается в производство, где списки могут быть огромными, а производительность замедляется до обхода. Это была такая общая ловушка, что было принято решение игнорировать утиную печать в этом случае и не допускать использования строк с sum
.
sum()
не просто вызывает ''.join()
, когда строка встречается в sum()
вместо того, чтобы возвращать ошибку, указав, что вы вызываете ''.join()
?
– Slater
28 April 2014 в 21:13
Вот источник: http://svn.python.org/view/python/trunk/Python/bltinmodule.c?revision=81029&view=markup
в функции builtin_sum мы имеем этот бит кода:..
/* reject string values for 'start' parameter */
if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
PyErr_SetString(PyExc_TypeError,
"sum() can't sum strings [use ''.join(seq) instead]");
Py_DECREF(iter);
return NULL;
}
Py_INCREF(result);
}
Так .. что ваш ответ
Это явно проверяется в коде и отвергнуто
Фактически вы можете использовать sum(..)
для конкатенации строк, если вы используете соответствующий начальный объект! Конечно, если вы заходите так далеко, вы уже достаточно поняли, чтобы использовать "".join(..)
в любом случае ..
>>> class ZeroObject(object):
... def __add__(self, other):
... return other
...
>>> sum(["hi", "there"], ZeroObject())
'hithere'
Из docs :
Предпочтительным, быстрым способом объединения последовательности строк является вызов '.join (sequence).
Делая
sum
отказаться от работы с строками, Python рекомендует вам использовать правильный метод.
sum
является неправильным инструментом для работы. sum
строит результат пошагово. Для этого со строками требуется (потенциально много) временных неизменяемых строк. Если это делается наивно, для этого процесса требуется много временной памяти и много копий. Напротив, если сделать это с ''.join()
, соответствующий объем памяти выделяется с самого начала, и результат строится прямо там сразу. См. увещевание Мартелли .
– unutbu
13 February 2014 в 15:56
reduce
иsum
похожи для списков, потому что они делают более или менее одно и то же. Вот почему я использовал этот тест:reduce
, представляющийsum
, по сравнению сjoin
, который является оптимизированным способом «добавления». строки. – rbp 19 August 2010 в 20:54sum
, они уже имелиjoin
для строк. Поэтому, чтобы избегать людей неосознанно (или сознательно, но лениво / озорно), используяsum
для строк, они специально запретили его. Поскольку не было конкретной «суммы», для списков (или других типов) они делали исключение только для строк. В настоящее время я думаю, что они сохранили бы его таким образом, даже если бы кто-то придумал конкретную «сумму» для обратной совместимости. – rbp 23 August 2010 в 01:46str.join
. Поскольку это была бы такая легкая оптимизация, я бы предположил, что намерение состоит в том, чтобы умышленно обманывать, чтобы научить людей существованиюstr.join
. – Ben 30 April 2014 в 22:41