Примените функцию к каждому элементу в 3 списках кортежей, чтобы получить 1 результирующий список python3 - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь вычислить результирующее ускорение по ускорениям x, y, z. Я написал функцию, которая делает это при ручном вводе координат x, y, z.

def Euclidean_norm(x,y,z):
    total = (x ** 2) + (y ** 2) + (z ** 2)
    resultant = math.sqrt(total)
    return resultant

Моя проблема в том, что я хочу использовать эту функцию для перебора трех списков и создания нового списка только с результирующим ускорением.

x_list = [(9.6,), (4.9,), (8.7,), (9.....]
y_list = [(0.6,), (2.6,), (4.6,), (2.....]
z_list = [(5.2,), (7.2,), (5.8,), (7.....]

Я пытался использовать функцию карты

print(map(Euclidean_norm(a,b,c)))

Однако это дало ошибку

TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'

Часть проблемы заключается в том, что значения x, y и z, которые я получаю из базы данных, получаются в виде кортежей вместо простых чисел.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

@ Отличный ответ Джоэддона показывает одно из нескольких возможных решений. Основная проблема заключается в том, что ваши кортежи распаковываются при вызове функции final. Возможно, вы захотите распаковать их сразу же после их возвращения из базы данных, поскольку ваш код, вероятно, ожидает, что:

x_list = [x[0] for x in x_list]

Немного более быстрая версия, которая будет хорошей идеей, если у вас очень большие списки, будет

from operator import itemgetter
g = itemgetter(0)
x_list = [g(x) for x in x_list]

После распаковки кортежей решение на молнии возвращается к первоначальному предложению:

resultant = [Euclidean_norm(x, y, z) for x, y, z in zip(x_list, y_list, z_list]

или альтернативно:

resultant = [Euclidean_norm(*accel) for accel in zip(x_list, y_list, z_list]

Другой вариант - придерживаться map, как вы пытались раньше. Проблема, с которой вы столкнулись, заключается в том, что синтаксис print(map(Euclidean_norm(a,b,c))) неправильно использует map. Выражение Euclidean_norm(a,b,c) фактически тут же вызывает Euclidean_norm со списками в качестве аргументов вместо передачи объекта функции в map. Вы хотели бы сделать что-то вроде map(Euclidean_norm, a, b, c):

resultant = list(map(Euclidean_norm, x_list, y_list, z_list))

Вам нужно применить list к map, потому что map возвращает генератор, который не будет оцениваться, пока вам не понадобятся элементы.

0 голосов
/ 26 апреля 2018

Используйте список-понимание с zip():

[Euclidean_norm(*x,*y,*z) for x,y,z in zip(x_list, y_list, z_list)]

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


Просто небольшое объяснение ...

Функция zip() берет любое количество итераций и объединяет их вместе, чтобы получить кортежи из соответствующих индексов. Это действительно полезная функция для перебора связанных списков, подобных приведенным здесь.

Чтобы продемонстрировать это немного яснее:

>>> a = [1, 2, 3]
>>> b = [2, 4, 6]
>>> list(zip(a, b))
[(1, 2), (2, 4), (3, 6)]
>>> for i, j in zip(a, b):
...     print(i, j)
... 
1 2
2 4
3 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...