Кортеж в списке имеет меньше элементов, чем требуется функции Python 3

Я новичок в программировании и 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 , но мне кажется, что я либо что-то упускаю, либо не знаю, какую функцию я мог бы использовать. Спасибо всем за помощь.

Использовать none вместо () и проверить его в своей функции?

MatBailie 06.06.2018 00:34

Есть разные способы решить вашу проблему. Один из способов решить эту проблему - перебрать кортеж в особом случае для len == 0. Если вы хотите решить более питоническим способом, вы можете взглянуть на понимание списка. Если вам понадобится дополнительная помощь, дайте мне знать.

pask 06.06.2018 00:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
76
5

Ответы 5

Один из способов - использовать 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, даже если он должен вернуть какое-то число, есть ли способ исправить это или я должен использовать решение из пользовательского паска?

DRT 06.06.2018 01:18

Большое спасибо! Мне просто интересно, что делает вещь yield. Это похоже на печать? Я посмотрю вокруг позже, если это слишком долго для комментария. Просто хочу отметить, что это книжное упражнение требует гораздо больше знаний и синтаксиса, которые до сих пор были представлены в нем, я думаю, что не всегда плохо исследовать вещи самостоятельно, но это доставило мне много проблем.

DRT 06.06.2018 01:24

@DRT, yield не является print; он представляет собой функцию генератора. Это ленивый способ получить результаты цикла for внутри функции. Вы можете преобразовать summary(xs) в print свои значения. Я обновился на примере.

jpp 06.06.2018 01:41

Что ж, проблема в том, что у вас недостаточно индексов во внутреннем кортеже для распаковки на три переменные. Самый простой способ обойти это - вручную распаковать после, проверяя, достаточно ли у вас переменных, то есть:

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 кортежей и т. д.), Но, тем не менее, это помогло. Большое спасибо!

DRT 06.06.2018 01:39

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

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, довольно простым и работающим безупречно. Думаю, моей самой большой проблемой было то, как я раньше просматривал кортежи, я был очень сбит с толку, что они вообще собой представляют, теперь я вижу, что это что-то вроде вложенных списков.

DRT 06.06.2018 01:16

Вы должны использовать условие "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» и работает для любой длины кортежа.

Потрясающие. Большое спасибо!

DRT 06.06.2018 01:19

Часто бывает выгодно разделить ваш алгоритм на функции, которые делают что-то одно. В этом случае функция суммирования квадратов списка значений и функция их печати. Очень полезно, чтобы имена переменных были значимыми. В этом случае ваш 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))))

Другие вопросы по теме