Подведите список чисел в Python


367

У меня есть список чисел, например [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?
kevpie

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

1
«Это не работает» не является описанием проблемы.
маркиз Лорн

Ответы:


279

Вопрос 1: Итак, вы хотите (элемент 0 + элемент 1) / 2, (элемент 1 + элемент 2) / 2, ... и т. Д.

Мы составляем два списка: один для каждого элемента, кроме первого, и один для каждого элемента, кроме последнего. Тогда средние значения, которые мы хотим, являются средними значениями каждой пары, взятыми из двух списков. Мы используем, zipчтобы взять пары из двух списков.

Я предполагаю, что вы хотите видеть десятичные дроби в результате, даже если ваши входные значения являются целыми числами. По умолчанию Python выполняет целочисленное деление: он отбрасывает остаток. Чтобы разделить вещи на всем пути, нам нужно использовать числа с плавающей точкой. К счастью, деление целого числа на число с плавающей точкой приведет к появлению числа с плавающей запятой, поэтому мы просто используем 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:])достаточно.
Chepner

115

Сумма списка номеров:

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 ...
Моберг

from functools import reduce
Tyrex

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
не нужно создавать такую ​​копию, и это ужасно непитонично. Избегайте чумы, несмотря на все голоса ...
Жан-Франсуа Фабр

@ Жан-Франсуа Фабр, не могли бы вы подробно изложить свой комментарий? Почему это "ужасно не пифонично"?
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])

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

Преимущество использования NumPy

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


1

Я бы просто использовал лямбду с map ()

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 Snippet:

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. Вы получите A на тесте для правильного ответа на вопрос, но ответы StackOverflow также должны быть полезны для людей, приходящих на эту страницу, а дублированные ответы - нет.
Нумен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.