Я новичок в программировании и Python, и я сам учусь перед поступлением в университет, поэтому, пожалуйста, будьте осторожны, я новичок. Надеюсь, в моем английском не будет слишком много грамматических ошибок.
В основном у меня было это упражнение в книге, которую я сейчас читаю, чтобы взять список кортежей в качестве параметра функции, а затем взять каждый элемент в каждом кортеже, поместить его во вторую степень и просуммировать элементы.
Мой код выглядит так и работает хорошо, если мой вызов функции включает такое же количество аргументов, какое требует функция для цикла:
def summary(xs):
for x,y,z in xs:
print( x*x + y*y + z*z)
xs =[(2,3,4), (2,-3,4), (1,2,3)]
summary(xs)
Однако, если я использую список с меньшим количеством кортежей, чем определение функции, я получаю сообщение об ошибке: ValueError: недостаточно значений для распаковки (ожидается 3, получено 0):
xs =[(2,3,4), (), (1,2,3)]
Я хотел бы знать, как создать функцию, которая будет принимать кортеж, который я показал перед () - без кортежей, и функция вернет 0. Я пробовал несколько способов решить эту проблему в течение 2 дней, а также искал в Google , но мне кажется, что я либо что-то упускаю, либо не знаю, какую функцию я мог бы использовать. Спасибо всем за помощь.
Есть разные способы решить вашу проблему. Один из способов решить эту проблему - перебрать кортеж в особом случае для len == 0. Если вы хотите решить более питоническим способом, вы можете взглянуть на понимание списка. Если вам понадобится дополнительная помощь, дайте мне знать.






Один из способов - использовать try / except. В приведенном ниже примере мы используем генератор и ловим случаи, когда распаковка завершается неудачно с ValueError и дает 0.
Пока вы учитесь, я настоятельно рекомендую вам попрактиковаться в написании функций типа return или yield, вместо того, чтобы использовать их для значений print.
def summary(xs):
for item in xs:
try:
yield sum(i**2 for i in item)
except ValueError:
yield 0
xs = [(2,3,4), (), (1,2,3)]
res = list(summary(xs))
print(res)
[29, 0, 14]
Или использовать генератор ленивым способом:
for i in summary(xs):
print(i)
29
0
14
Спасибо, это тоже работает, если я использую 3 кортежа или нет кортежей.Если я использую, скажем, 2 кортежа в списке, он возвращает 0, даже если он должен вернуть какое-то число, есть ли способ исправить это или я должен использовать решение из пользовательского паска?
Большое спасибо! Мне просто интересно, что делает вещь yield. Это похоже на печать? Я посмотрю вокруг позже, если это слишком долго для комментария. Просто хочу отметить, что это книжное упражнение требует гораздо больше знаний и синтаксиса, которые до сих пор были представлены в нем, я думаю, что не всегда плохо исследовать вещи самостоятельно, но это доставило мне много проблем.
@DRT, yield не является print; он представляет собой функцию генератора. Это ленивый способ получить результаты цикла for внутри функции. Вы можете преобразовать summary(xs) в print свои значения. Я обновился на примере.
Что ж, проблема в том, что у вас недостаточно индексов во внутреннем кортеже для распаковки на три переменные. Самый простой способ обойти это - вручную распаковать после, проверяя, достаточно ли у вас переменных, то есть:
def summary(xs):
for values in xs:
if values and len(values) == 3:
x, y, z = values # or don't unpack, refer to them by index, i.e. v[0], v[1]...
print(x*x + y*y + z*z)
else:
print(0)
Или используйте блок try..except:
def summary(xs):
for values in xs:
try:
x, y, z = values # or don't unpack, refer to them by index, i.e. v[0], v[1]...
print(x*x + y*y + z*z)
except ValueError: # check for IndexError if not unpacking
print(0)
Потрясающие. Я только что немного отредактировал код, чтобы он работал с любыми кортежами (2 кортежа, 5 кортежей и т. д.), Но, тем не менее, это помогло. Большое спасибо!
Один из способов - перебрать значения кортежа, это также способ решить эту проблему почти на каждом языке программирования:
def summary(xs):
for item in xs:
s = 0
for value in item:
s += value**2
print(s)
Или используя понимание списка:
def summary(xs):
for item in xs:
result = sum([x**2 for x in item])
print(result)
также обратите внимание, что sum([]) вернет 0 для пустой итерации.
Большое спасибо. Я понятия не имею, как я не подумал о зацикливании кортежей, сделав вложенный цикл for, довольно простым и работающим безупречно. Думаю, моей самой большой проблемой было то, как я раньше просматривал кортежи, я был очень сбит с толку, что они вообще собой представляют, теперь я вижу, что это что-то вроде вложенных списков.
Вы должны использовать условие "len> 0". Этот код должен работать для любого списка или длины кортежа:
def summary(xs):
for tup in xs:
prod = [a*a for a in tup if len(tup)>0]
print(sum(prod))
Обратите внимание, что я определил список «prod», чтобы использовать «сумму», чтобы она не вычислялась жестко. Он заменяет ваш «x * x + y * y + z * z» и работает для любой длины кортежа.
Потрясающие. Большое спасибо!
Часто бывает выгодно разделить ваш алгоритм на функции, которые делают что-то одно. В этом случае функция суммирования квадратов списка значений и функция их печати. Очень полезно, чтобы имена переменных были значимыми. В этом случае ваш xs представляет собой список списков, поэтому его лучше назвать xss.
import math
def sum_of_squares(xs):
return sum(map(math.sqr, xs))
def summary(xss):
for xs in xss:
print sum_of_squares(xs)
xss = [(2,3,4), (), (1,2,3)]
summary(xss)
или же
map(print, sum(map(math.sqr, (x for x in xs))))
Использовать
noneвместо()и проверить его в своей функции?