Python'daki sayıların listesini toplama


367

Gibi sayıların bir listesi var [1,2,3,4,5...]ve hesaplamak istiyorum (1+2)/2ve ikinci (2+3)/2ve üçüncü için, (3+4)/2 vb. Bunu nasıl yapabilirim?

İlk sayıyı ikincisiyle toplamak ve 2'ye bölmek, sonra ikincisini üçüncüyle toplamak ve 2'ye bölmek istiyorum.

Ayrıca, bir sayı listesini nasıl toplayabilirim?

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

Bu mu:

b = sum(a)
print b

bir numara almak için?

Bu benim için işe yaramıyor.


Bu liste ne kadar sürüyor? 0 ile 1 arasındaki değerler ne kadar rastgele?
kevpie

2
toplamı python'u karıştırmadan önce tanımlarsanız del sum'ı deneyin. belki kodda bir yerde tanımlanmış ve varsayılan fonksiyonun üzerine yazmış olabilir. Bu yüzden sildim ve sorun çözüldü. (user4183543 tarafından cevap)
NicoKowe

1
"Bu işe yaramaz" bir sorun açıklaması değildir.
Lorne Marquis

Yanıtlar:


279

Soru 1: Böylece (eleman 0 + eleman 1) / 2, (eleman 1 + eleman 2) / 2, ... vb.

İki liste yapıyoruz: ilk hariç her öğeden biri ve son hariç her öğeden biri. O zaman istediğimiz ortalamalar, her bir çiftin iki listeden alınan ortalamalarıdır. Kullanırızzipİki listeden ikili almak için .

Girdi değerleriniz tamsayı olmasına rağmen sonuçta ondalık sayıları görmek istediğinizi varsayalım. Varsayılan olarak, Python tamsayı bölümü yapar: geri kalanını atar. İşleri sonuna kadar bölmek için kayan nokta sayıları kullanmamız gerekir. Neyse ki, bir int'i bir şamandıra ile bölmek bir şamandıra üretecektir, bu yüzden sadece 2.0bölücümüz için değil2 .

Böylece:

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

Soru 2:

Bu kullanımı sumiyi çalışmalıdır. Aşağıdaki işler:

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

Ayrıca, yol boyunca her adımda her şeyi bir değişkene atamanıza gerek yoktur. print sum(a)gayet iyi çalışıyor.

Tam olarak ne yazdığınız ve nasıl çalışmadığı hakkında daha spesifik olmanız gerekir.


alamadım, ilk soru için my_list tanımsız aldım. Programımda rasgele bir sayı değil 1, 2, 3, 4 .. ikinci soru için benimle çalışmıyor ben neden bilmiyorum
layo

37
my_listyalnızca tanımladığınızda tanımlanır. Bu, üzerinde çalıştığınız liste adını verdiğiniz her şey için bir yer tutucusuydu. Ne dediğini tahmin edemiyorum.
Karl Knechtel

2
6 yıl sonra bu yazı hala insanlara yardım ediyor. Kodumda bir aksaklık vardı ve kodumu kendiniz için ilgili kavramların da doğru olduğunu onaylamak için yazınızı kullanabildim, bu yüzden sorun başka bir yerde olmalı. Sonra buldum. Sadece size ve soruya sahip kişiye hızlı bir teşekkür olarak yukarı oy verdiniz. En iyi dileklerimle.
TMWP

1
@KarlKnechtel Sorusunda bir liste vardı ve buna " a" adı verildi .
HelloGoodbye

1
Daha zipkısa argümanın sonuna ulaştığında durur zip(my_list, my_list[1:]), yeterlidir.
chepner

115

Toplam sayı listesi:

sum(list_of_nums)

Bir liste kavrama kullanarak n ve n - 1 yarısını hesaplamak (eğer desen doğru varsa) :

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

Toplam bitişik elemanlar, örn. ((1 + 2) / 2) + ((2 + 3) / 2) + ... azaltma ve lambdalar kullanarak

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

4
Sanırım bitişik unsurları toplamak istiyor. Ortalaması alınarak anlamı yok olacağını xve x - 1; bunun yerine 0,5 çıkarabiliriz.
Karl Knechtel

4
İndirgeme işlevi yazının söylediklerini yapmaz. Hesaplar (((a1 + a2) / 2 + a3) / 2 + a4) / 2 ...
Moberg

from functools import reduce
tyrex

70

Soru 2: Tamsayıların bir listesini toplamak için:

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

Listede dize olarak tamsayılar varsa:

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

4
sum(i for i in a)sadece gereksizdir.
Jean-François Fabre

6
sum(Decimal(i) for i in a)=> sum(int(i) for i in a)veyasum(map(int,a))
Jean-François Fabre

34

Bu şekilde deneyebilirsiniz:

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
böyle bir kopya oluşturmaya gerek yok ve bu korkunç bir şekilde unpythonic. Tüm oylara rağmen veba gibi kaçının ...
Jean-François Fabre

@ Jean-FrançoisFabre, yorumunuzu ayrıntılarıyla anlatır mısınız? Neden bu "korkunç bir şekilde tefleksiz"?
PierreF

yeni başlayanlar için a[0:len(a)]bir kopyasını oluşturur a, CPU ve bellek israfının yanı sıra ne? sonra print(sm)da python 2'de çalışıyor. 2017'nin ortasında neden bu kadar çok oy verildiğini anlamıyorum ... ama buradaki cevapların çoğu için geçerlidir.
Jean-François Fabre

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

sumKodda bir yerde tanımlanmış gibi görünüyor ve varsayılan işlevin üzerine yazılıyor. Bu yüzden sildim ve sorun çözüldü.


16

Basit list-comprehensionve kullanarak sum:

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

4
Kullanmanıza gerek yok [ve ]sadece jeneratör ifadesini geçebilirsinizsum(i/2. for i in range(x))
Ivan

1
sum(range(x)) / 2.tüm bölünmelerden kaçınır, sonunda bölün.
Jean-François Fabre

13

Tüm cevaplar programlı ve genel bir yaklaşım gösterdi. Sizin durumunuza özgü matematiksel bir yaklaşım öneriyorum. Özellikle uzun listeler için daha hızlı olabilir. Bu, listeniz en fazla doğal sayının bir listesi olduğu için çalışırn :

Doğal sayılara sahip olduğumuzu varsayalım 1, 2, 3, ..., 10:

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

Bu sumişlevi bir listede kullanabilirsiniz:

>>> print sum(nat_seq)
55

Ayrıca formülü kullanabilirsiniz : (burada listedeki son elemanın değeridir sen elemanları üzerinde iterating önlemek, böylece):n*(n+1)/2nnat_seq[-1]

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

Diziyi oluşturmak için (1+2)/2, (2+3)/2, ..., (9+10)/2bir jeneratör ve formül kullanabilirsiniz (2*k-1)/2.(kayan noktaları yapmak için noktayı not edin). Yeni listeyi oluştururken ilk öğeyi atlamanız gerekir:

>>> 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]

Burada da sumbu listedeki işlevi kullanabilirsiniz :

>>> print sum(new_seq)
49.5

Ancak formülü de kullanabilirsiniz (((n*2+1)/2)**2-1)/2, böylece öğeler üzerinde yinelemeyi önleyebilirsiniz:

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

6

Bu sorunu çözmenin en basit yolu:

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

4

Bu soru burada cevaplandı

a = [1,2,3,4] toplam (a) 10 değerini döndürür


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

Jeneratörler bunu yazmanın kolay bir yoludur:

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]

Tamsayı bölünmesini önlemek için 2.0'a bölebilirsiniz.
Chris Anderson

@ChrisAnderson python 3'te doğru değil. Kayan nokta bölümü varsayılan değerdir.
Justin Meiners

3

Başlangıç ​​için kolaylaştıralım: -

  1. globalAnahtar kelime yeni yerel değişken üretmeden genel değişken mesajı ana işlevi içinde atanacak sağlayacak
    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

Bu konsepte Gölgeleme denir

  1. Python'daki sayıların listesini toplama
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()

Çıkışlar = 15


2

pairwise Itertools tarifini kullanma :

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

Kısa ve basit:

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

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

İşte böyle görünüyor:

>>> 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'un mapikiden fazla listeyi işleme biçimindeki bazı aptallıklardan dolayı , listeyi kısaltmanız gerekir a[:-1]. Kullanırsanız beklediğiniz gibi çalışır 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]

Kısa, evet. Basit? Ne yaptığını anlamak için uzun çözümlerden daha uzun bir açıklama gerektirir.
tekHedd

bu kayan nokta biriktirme hatası verir. Bunun yerine sonuna bölün.
Jean-François Fabre

1
@ Jean-FrançoisFabre Her iki yöntem de kusurludur - sonunda bölmek büyük sayılar için taşacaktır, çözüm verilere (ve kullanım durumuna) bağlıdır.
cz

2

Çok fazla çözüm var, ancak favorim hala eksik:

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

bir numpy dizisi bir listeden çok farklı değildir (bu kullanım durumunda), sayılar gibi dizileri tedavi edebilmeniz dışında:

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

Bitti!

açıklama

Süslü endeksler şu anlama gelir: [1:]1'den sonuna kadar tüm elemanları içerir (böylece 0 elemanını atlar) ve [:-1]sonuncusu hariç tüm elemanlardır:

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

Bu ikisini eklemek size elemen (1 + 2), (2 + 3) ve benzerlerinden oluşan bir dizi verir. Ben bölüyorum 2.0değil, 2aksi takdirde Python sadece tamsayı kullandığınıza inanıyor ve yuvarlak tamsayı sonuçları üretiyor.

numpy kullanmanın avantajı

Numpy, sayı listelerinin etrafındaki döngülerden çok daha hızlı olabilir . Listenizin ne kadar büyük olduğuna bağlı olarak, birkaç büyüklük sırası daha hızlıdır. Ayrıca, çok daha az kod ve en azından benim için okumak daha kolay. Tüm sayı grupları için numpy kullanma alışkanlığı yapmaya çalışıyorum ve aksi takdirde yapmak zorunda olduğum tüm döngüler ve döngüler içinde büyük bir gelişme.


1

Sadece harita ile bir lambda kullanırdım ()

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

whileSonuç almak için bir döngü kullanın:

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

1

Listedeki öğeleri gözden geçirin ve toplamı şu şekilde güncelleyin:

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

1

Sayesinde Karl Knechtel i sorunuzu anlayabildim. Benim yorumum:

  1. İ ve i + 1 öğelerinin ortalamasını içeren yeni bir liste istiyorsunuz.
  2. Listedeki her öğeyi toplamak istiyorsunuz.

Anonim işlev kullanan ilk soru (diğer adıyla Lambda işlevi):

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

İkinci soru ayrıca anonim işlev kullanarak da (diğer adıyla Lambda işlevi):

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

Her iki soru da tek bir kod satırında birleştirildi:

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

ihtiyaçlarınıza en uygun olanı kullanın


1

Aynı şeyi özyineleme kullanarak da yapabilirsiniz:

Python Snippet'i:

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

Bir liste kavrayışı kullanmayı deneyin. Gibi bir şey:

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

@Rafe bu işe yarıyor (sonunda parantezleri düzeltirsek - olması gerekir range(len(old_list) - 1)), ancak Pythonistas genellikle 'aralık' ve 'len' kombinasyonuna kaşlarını çattı. "Bunu yapmanın tek bir yolu olmalı" ifadesi, "standart kütüphane çirkin şeylerden kaçınmanız için bir yol sağlar" dır. Dolaylı yineleme - bir sayı dizisi üzerinde yineleme, böylece gerçekten yinelemek istediğiniz şeyi indekslemek için bu numaraları kullanabilirsiniz - çirkin bir şeydir.
Karl Knechtel

0

Itertools ruhunda. İkili tariften ilham.

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))

Örnekler:

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

Basit bir yol iter_tools permütasyonunu kullanmaktır

# 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)

Sonuç:

[(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 anlamına gelen sipariş konularının da 2, 1, 7 ve 7, 1, 2 olarak gösterildiğini unutmayın. Bir küme kullanarak bunu azaltabilirsiniz.


0

Python 3.8'de, yeni atama operatörü kullanılabilir

>>> 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]

alistedeki önceki değere çalışan bir referanstır , bu nedenle listenin ilk öğesine başlatılır ve yineleme listenin geri kalanında gerçekleşir ve aher yinelemede kullanıldıktan sonra güncellenir .

Kullanarak listenin bir kopyasını oluşturmak zorunda kalmamak için açık bir yineleyici kullanılır my_list[1:].


-3

Takip etmeyi dene -

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
Yeni bir cevap, mevcut cevaplardan gerçekten farklı olmalıdır. Ayrıca, sumişleviniz yerleşik sumdavranış veya addan farklı değildir . İşlev tanımını yanıtınızdan silebilirsiniz ve yine de çalışır.
Noumenon

lütfen şimdi kontrol edebilir misiniz
Sai G

2
Cevabınızı geliştirdiğiniz için teşekkür ederiz! Değişken adları daha açıklayıcıdır ve yerleşik gölgeleri oluşturmaz. Ancak temel sorunlar hala var: for-loop yaklaşımı yukarıda stackoverflow.com/a/35359188/733092 tarafından zaten sağlanmıştı ve işlev yerleşik ile gereksizdir sum. Soruyu doğru cevaplamak için bir testte A alırsınız, ancak StackOverflow cevaplarının da bu sayfaya gelen insanlar için yararlı olması gerekir ve yinelenen cevaplar değildir.
Noumenon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.