Підсумуйте список номерів у Python


366

У мене є список таких чисел, як [1,2,3,4,5...]і я хочу обчислити(1+2)/2 і для другого, (2+3)/2і для третього (3+4)/2, і так далі. Як я можу це зробити?

Я хотів би підсумовувати перше число з другим і ділити його на 2, потім підсумовувати друге з третім і ділити на 2 тощо.

Крім того, як можна підсумовувати список номерів?

a = [1, 2, 3, 4, 5, ...]

Є це:

b = sum(a)
print b

щоб отримати одне число?

Це не працює для мене.


Скільки триває цей список? наскільки випадкові значення між 0 і 1?
кевпі

2
якщо ви визначите суму до того, як вона могла зіпсувати пітон, спробуйте del sum. можливо, він десь визначений у коді і перезаписує функцію за замовчуванням. Тож я її видалив, і проблема була вирішена. (відповідь user4183543)
NicoKowe

1
"Це не працює" - це не опис проблеми.
Маркіз Лорн

Відповіді:


279

Питання 1: Отже, ви хочете (елемент 0 + елемент 1) / 2, (елемент 1 + елемент 2) / 2, ... і т.д.

Складаємо два списки: один з кожного елемента, крім першого, і один з кожного елемента, крім останнього. Тоді середні значення, які ми хочемо, - це середні значення кожної пари, взяті з двох списків. Ми zipберемо пари з двох списків.

Я припускаю, що ви хочете побачити десяткові знаки в результаті, навіть якщо ваші вхідні значення є цілими числами. За замовчуванням Python робить цілочисельний поділ: він відкидає решту. Щоб розділити речі на весь шлях, нам потрібно використовувати числа з плаваючою комою. На щастя, розділення int на float призведе до поплавця, тому ми просто використовуємо 2.0для нашого дільника замість 2.

Таким чином:

averages = [(x + y) / 2.0 for (x, y) in zip(my_list[:-1], my_list[1:])]

Питання 2:

Таке використання sumмає справно працювати. Наступні роботи:

a = range(10)
# [0,1,2,3,4,5,6,7,8,9]
b = sum(a)
print b
# Prints 45

Крім того, вам не потрібно призначати все змінній на кожному кроці на цьому шляху. print sum(a)працює просто чудово.

Вам доведеться бути більш конкретними щодо того, що саме ви написали та як це не працює.


я не потрапив, за першим питанням я визначив my_list невизначеним. У моїй програмі його випадкове число не 1, 2, 3, 4 .. для другого питання я не працюю зі мною, я не знаю, чому
layo

37
my_listвизначається лише в тому випадку, якщо ви його визначите. Це повинно було бути власником місць для того, що ви називали списком, з яким ви намагаєтесь працювати. Я не можу здогадатися, як ти це назвав.
Карл Кнечтел

2
Через 6 років ця посада все ще допомагає людям. У мене виникли збої в моєму коді, і я зміг використати вашу публікацію, щоб підтвердити, що пов'язані поняття в моєму коді з вашим також були правильні, тому проблема повинна лежати в іншому місці. Потім я його знайшов. Щойно подякував вам та людині, яка поставила запитання, як швидке подяку. Найкращі побажання.
TMWP

1
@KarlKnechtel У нього було список, і він називався " a".
HelloGoodbye

1
Оскільки zipзупиняється, як тільки вона доходить до кінця коротшого аргументу, zip(my_list, my_list[1:])достатньо.
чепнер

114

Підсумковий список номерів:

sum(list_of_nums)

Обчислення половини n і n - 1 (якщо я маю правильну схему), використовуючи розуміння списку :

[(x + (x - 1)) / 2 for x in list_of_nums]

Підсумовуйте суміжні елементи, наприклад ((1 + 2) / 2) + ((2 + 3) / 2) + ... за допомогою скорочення та лямбда

reduce(lambda x, y: (x + y) / 2, list_of_nums)

4
Я думаю, що він хоче підсумувати суміжні елементи. Не було б сенсу брати середнє значення xта x - 1; ми могли б просто відняти 0,5.
Карл Кнечтел

4
Функція зменшення не робить те, що йдеться у публікації. Він обчислює (((a1 + a2) / 2 + a3) / 2 + a4) / 2 ...
Moberg

from functools import reduce
тирекс

70

Питання 2: Підсумовувати список цілих чисел:

a = [2, 3, 5, 8]
sum(a)
# 18
# or you can do:
sum(i for i in a)
# 18

Якщо список містить цілі числа у вигляді рядків:

a = ['5', '6']
# import Decimal: from decimal import Decimal
sum(Decimal(i) for i in a)

4
sum(i for i in a)просто зайве.
Жан-Франсуа Фабре

6
sum(Decimal(i) for i in a)=> sum(int(i) for i in a)абоsum(map(int,a))
Жан-Франсуа Фабре

34

Можна спробувати так:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sm = sum(a[0:len(a)]) # Sum of 'a' from 0 index to 9 index. sum(a) == sum(a[0:len(a)]
print(sm) # Python 3
print sm  # Python 2

4
не потрібно створювати подібну копію, і це жахливо непітонічно. Уникайте чуми, незважаючи на всі голоси ...
Жан-Франсуа Фабре

@ Jean-FrançoisFabre Ви можете, будь ласка, деталізувати свій коментар? Чому це "жахливо непітонічне"?
PierreF

для початківців a[0:len(a)]створюється копія a, який сенс крім того, щоб витрачати процесор та пам'ять? потім print(sm)також працює в python 2. Я не розумію, чому в середині 2017 року так багато оновлень ... але це стосується більшості відповідей тут.
Жан-Франсуа Фабре

27
>>> a = range(10)
>>> sum(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> del sum
>>> sum(a)
45

Здається, що sumдесь визначено в коді і перезаписує функцію за замовчуванням. Тож я її видалив, і проблема була вирішена.


16

Використання простого list-comprehensionта sum:

>> sum(i for i in range(x))/2. #if x = 10 the result will be 22.5

4
Не потрібно використовувати, [і ]ви можете просто передати вираз генератораsum(i/2. for i in range(x))
Іван

1
sum(range(x)) / 2.уникає всіх підрозділів, просто ділимо врешті-решт.
Жан-Франсуа Фабре

13

Усі відповіді демонстрували програмний та загальний підхід. Я пропоную математичний підхід, специфічний для вашого випадку. Це може бути швидше, зокрема для довгих списків. Це працює, оскільки ваш список - це список природних чиселn :

Припустимо, що у нас є натуральні числа 1, 2, 3, ..., 10:

>>> nat_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Ви можете використовувати sumфункцію у списку:

>>> print sum(nat_seq)
55

Ви також можете використовувати формулу, n*(n+1)/2де nзначення останнього елемента в списку (тут nat_seq[-1]:), так що ви уникаєте повторення елементів:

>>> print (nat_seq[-1]*(nat_seq[-1]+1))/2
55

Для генерації послідовності (1+2)/2, (2+3)/2, ..., (9+10)/2можна використовувати генератор та формулу (2*k-1)/2.(відзначте крапку, щоб зробити значення плаваючими точками). Перший елемент потрібно пропустити під час створення нового списку:

>>> new_seq = [(2*k-1)/2. for k in nat_seq[1:]]
>>> print new_seq
[1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]

І тут ви можете використовувати sumфункцію у цьому списку:

>>> print sum(new_seq)
49.5

Але ви також можете використовувати формулу (((n*2+1)/2)**2-1)/2, щоб уникнути повторення елементів:

>>> print (((new_seq[-1]*2+1)/2)**2-1)/2
49.5

6

Найпростіший спосіб вирішити цю проблему:

l =[1,2,3,4,5]
sum=0
for element in l:
    sum+=element
print sum


3
import numpy as np    
x = [1,2,3,4,5]
[(np.mean((x[i],x[i+1]))) for i in range(len(x)-1)]
# [1.5, 2.5, 3.5, 4.5]

3

Генератори - це простий спосіб написати це:

from __future__ import division
# ^- so that 3/2 is 1.5 not 1

def averages( lst ):
    it = iter(lst) # Get a iterator over the list
    first = next(it)
    for item in it:
        yield (first+item)/2
        first = item

print list(averages(range(1,11)))
# [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]

Ви також можете розділити на 2.0, щоб уникнути цілого поділу.
Кріс Андерсон

@ChrisAnderson не вірно в python 3. поділ з плаваючою комою є типовим.
Джастін Майнер

3

Давайте полегшимо для початківців: -

  1. globalКлючових слів дозволить повідомлення глобальної змінної присвоюється в основної функції , не роблячи нову локальну змінну
    message = "This is a global!"


def main():
    global message
    message = "This is a local"
    print(message)


main()
# outputs "This is a local" - From the Function call
print(message)
# outputs "This is a local" - From the Outer scope

Ця концепція називається Shadowing

  1. Підсумуйте список номерів у Python
nums = [1, 2, 3, 4, 5]

var = 0


def sums():
    for num in nums:
        global var
        var = var + num
    print(var)


if __name__ == '__main__':
    sums()

Виходи = 15


2

Використовуючи pairwise рецепт itertools :

import itertools
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return itertools.izip(a, b)

def pair_averages(seq):
    return ( (a+b)/2 for a, b in pairwise(seq) )

2

Короткий і простий:

def ave(x,y):
  return (x + y) / 2.0

map(ave, a[:-1], a[1:])

А ось як це виглядає:

>>> a = range(10)
>>> map(ave, a[:-1], a[1:])
[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]

З - за який - то дурниці , в тому , як Python підтримує ще mapбільше двох списків, ви повинні відсікти список, a[:-1]. Він працює більше, як ви очікували, якщо використовуєте itertools.imap:

>>> import itertools
>>> itertools.imap(ave, a, a[1:])
<itertools.imap object at 0x1005c3990>
>>> list(_)
[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]

Коротко, так. Простий? Щоб зрозуміти, що це робить, потрібне пояснення довше, ніж довгі рішення.
tekHedd

це вводить помилку накопичення плаваючої точки. Зрештою, розділіть натомість.
Жан-Франсуа Фабре

1
@ Jean-FrançoisFabre Обидва способи недосконалі - розділення в кінці буде переповнено для великих чисел, рішення залежить від даних (та випадку використання).
cz

2

Стільки рішень, але мого улюбленого все ще немає:

>>> import numpy as np
>>> arr = np.array([1,2,3,4,5])

масив numpy не надто відрізняється від списку (у цьому випадку використання), за винятком того, що ви можете обробляти масиви як числа:

>>> ( arr[:-1] + arr[1:] ) / 2.0
[ 1.5  2.5  3.5  4.5]

Готово!

пояснення

Файлові індекси означають це: [1:]включає всі елементи від 1 до кінця (таким чином опускаючи елемент 0), і [:-1]всі елементи, крім останнього:

>>> arr[:-1]
array([1, 2, 3, 4])
>>> arr[1:]
array([2, 3, 4, 5])

Таким чином, додавання цих двох дає вам масив, що складається з елементів (1 + 2), (2 + 3) тощо. Не те, що я поділяю на 2.0, не 2тому, що в іншому випадку Python вважає, що ви використовуєте лише цілі числа і виробляє округлі цілі результати.

Перевага використання numpy

Numpy може бути набагато швидше, ніж петлі навколо списків чисел. Залежно від того, наскільки великий ваш список, на кілька порядків швидше. Також це набагато менше коду, і, принаймні, мені це легше читати. Я намагаюся створити звичку використовувати numpy для всіх груп чисел, і це величезне вдосконалення для всіх циклів і циклів, що я б інакше повинен був зробити.


1

Я просто використовую лямбда з картою ()

a = [1,2,3,4,5,6,7,8,9,10]
b = map(lambda x, y: (x+y)/2.0, fib[:-1], fib[1:])
print b

1

Я використовую whileцикл, щоб отримати результат:

i = 0
while i < len(a)-1:
   result = (a[i]+a[i+1])/2
   print result
   i +=1

1

Проведіть прокручування елементів у списку та оновіть загальну суму так:

def sum(a):
    total = 0
    index = 0
    while index < len(a):
        total = total + a[index]
        index = index + 1
    return total

1

Завдяки Карлу Кнечтелю я зміг зрозуміти ваше запитання. Моє тлумачення:

  1. Ви хочете новий список із середнім значенням елемента i та i + 1.
  2. Ви хочете підсумувати кожен елемент у списку.

Перше запитання з використанням анонімної функції (ака. Функція лямбда):

s = lambda l: [(l[0]+l[1])/2.] + s(l[1:]) if len(l)>1 else []  #assuming you want result as float
s = lambda l: [(l[0]+l[1])//2] + s(l[1:]) if len(l)>1 else []  #assuming you want floor result

Друге питання також з використанням анонімної функції (ака. Функція лямбда):

p = lambda l: l[0] + p(l[1:]) if l!=[] else 0

Обидва питання об'єднані в один рядок коду:

s = lambda l: (l[0]+l[1])/2. + s(l[1:]) if len(l)>1 else 0  #assuming you want result as float
s = lambda l: (l[0]+l[1])/2. + s(l[1:]) if len(l)>1 else 0  #assuming you want floor result

використовуйте той, який найкраще відповідає вашим потребам


1

Ви можете зробити те ж саме, використовуючи рекурсію:

Фрагмент Python:

def sumOfArray(arr, startIndex):
    size = len(arr)
    if size == startIndex:  # To Check empty list
        return 0
    elif startIndex == (size - 1): # To Check Last Value
        return arr[startIndex]
    else:
        return arr[startIndex] + sumOfArray(arr, startIndex + 1)


print(sumOfArray([1,2,3,4,5], 0))

0

Спробуйте використати розуміння списку. Щось на зразок:

new_list = [(old_list[i] + old_list[i+1])/2 for i in range(len(old_list-1))]

@Rafe - це робочий (якщо ми просто виправляємо круглі дужки в кінці - так і повинно бути range(len(old_list) - 1)), але Pythonistas, як правило, нахмуриться на комбінацію 'range' і 'len'. Наслідок "має бути лише один спосіб зробити це" - "стандартна бібліотека забезпечує спосіб уникнути негарних речей". Непряма ітерація - повторення по послідовності чисел, щоб ви могли використовувати ці числа для індексації того, що ви насправді хочете повторити, - жахлива річ.
Карл Кнечтел

0

У дусі itertools. Натхнення з парного рецепту.

from itertools import tee, izip

def average(iterable):
    "s -> (s0,s1)/2.0, (s1,s2)/2.0, ..."
    a, b = tee(iterable)
    next(b, None)
    return ((x+y)/2.0 for x, y in izip(a, b))

Приклади:

>>>list(average([1,2,3,4,5]))
[1.5, 2.5, 3.5, 4.5]
>>>list(average([1,20,31,45,56,0,0]))
[10.5, 25.5, 38.0, 50.5, 28.0, 0.0]
>>>list(average(average([1,2,3,4,5])))
[2.0, 3.0, 4.0]

0
n = int(input("Enter the length of array: "))
list1 = []
for i in range(n):
    list1.append(int(input("Enter numbers: ")))
print("User inputs are", list1)

list2 = []
for j in range(0, n-1):
    list2.append((list1[j]+list1[j+1])/2)
print("result = ", list2)

0

Простий спосіб - використовувати перестановку iter_tools

# If you are given a list

numList = [1,2,3,4,5,6,7]

# and you are asked to find the number of three sums that add to a particular number

target = 10
# How you could come up with the answer?

from itertools import permutations

good_permutations = []

for p in permutations(numList, 3):
    if sum(p) == target:
        good_permutations.append(p)

print(good_permutations)

Результат:

[(1, 2, 7), (1, 3, 6), (1, 4, 5), (1, 5, 4), (1, 6, 3), (1, 7, 2), (2, 1, 7), (2, 3, 
5), (2, 5, 3), (2, 7, 1), (3, 1, 6), (3, 2, 5), (3, 5, 2), (3, 6, 1), (4, 1, 5), (4, 
5, 1), (5, 1, 4), (5, 2, 3), (5, 3, 2), (5, 4, 1), (6, 1, 3), (6, 3, 1), (7, 1, 2), 
(7, 2, 1)]

Зверніть увагу, що питання порядку - значення 1, 2, 7 також показані як 2, 1, 7 і 7, 1, 2. Ви можете зменшити це за допомогою набору.


0

У Python 3.8 можна використовувати новий оператор призначення

>>> my_list = [1, 2, 3, 4, 5]
>>> itr = iter(my_list)
>>> a = next(itr)
>>> [(a + (a:=x))/2 for x in itr]
[1.5, 2.5, 3.5, 4.5]

aє поточним посиланням на попереднє значення у списку, отже, воно ініціалізується на перший елемент списку, а ітерація відбувається над рештою списку, оновлюючись aпісля його використання в кожній ітерації.

Явний ітератор використовується для уникнення необхідності створення копії списку за допомогою my_list[1:].


-3

Спробуйте наступне -

mylist = [1, 2, 3, 4]   

def add(mylist):
    total = 0
    for i in mylist:
        total += i
    return total

result = add(mylist)
print("sum = ", result)

2
Нова відповідь дійсно повинна відрізнятися від існуючих відповідей. Також ваша sumфункція не відрізняється від вбудованої sumповедінки чи імені. Ви фактично можете видалити визначення функції зі своєї відповіді, і воно все одно буде працювати.
Номенон

Ви можете будь ласка перевірити зараз
Sai G

2
Я вдячний, що ви вдосконалюєте свою відповідь! Імена змінних більш описові і не затінюють вбудовані модулі. Але основні проблеми все ще існують: підхід for-loop був уже наданий stackoverflow.com/a/35359188/733092 вище, а функція є надмірною убудованою sum. Ви отримаєте тест "А", щоб правильно відповісти на питання, але відповіді StackOverflow також повинні бути корисними людям, які приїжджають на цю сторінку, а дублюючі відповіді - ні.
Номенон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.