Необходимо написать программу, которая считывает со стандартного ввода целые числа по одному числу и после первого введённого нуля – выводит сумму полученных на вход чисел.
Не понимаю – где ошибка?
text = int(input("Вводите значение: ")) # вводим элементы массива
while text != (int(0)): # цикл - до тех пор, пока -text != 0, добавляет значения в массив -a
a.append(text) # добавляем значение в массив
if text == (int(0)): # если -text == 0, выводим сумму всех элементов массива
print(sum(a)) # суммируем между собой все элементы массива
user207200
5,0908 золотых знаков23 серебряных знака41 бронзовый знак
задан 7 дек 2020 в 8:04
3
У вас не объявлен список a
.
Бесконечный цикл работает не так, как нужно. На каждой итерации цикла после добавления нужно запрашивать новое значение.
text = int(input("Вводите значение: ")) # вводим элементы массива
a = []
while text != 0: # цикл - до тех пор, пока -text != 0, добавляет значения в массив -a
a.append(text) # добавляем значение в массив
text = int(input("Вводите значение: "))
print(sum(a)) # суммируем между собой все элементы массива
ответ дан 7 дек 2020 в 8:14
ioprstioprst
1,2187 серебряных знаков17 бронзовых знаков
1
Вы вводите число одни раз в самом начале.
Допустим, вы ввели 9. Далее цикл выполняется, пока 9 != 0
, то есть бесконечно, так как новые числа не вводятся. Нужно просто добавить ввод данных в цикл.
Также можно перенести вывод суммы из цикла, чтобы не проверять условие каждый раз.
И ещё, нет никакого смысла в записи int(0)
Например, можно сделать так:
arr = []
num = int(input("Вводите значение: "))
while num != 0:
num = int(input("Вводите значение: "))
arr.append(num)
print(sum(arr))
ответ дан 7 дек 2020 в 8:14
NoNameNoName
1897 бронзовых знаков
1
Лучше в данном случае использовать “бесконечный цикл”, чтобы ввод значения не делать два раза в разных местах:
a = []
while True:
num = int(input("Вводите значение: "))
if num == 0:
print(sum(a))
break
a.append(num)
Ну а ошибки и недочёты вам уже все написали в других ответах.
ответ дан 7 дек 2020 в 8:17
CrazyElfCrazyElf
65.4k5 золотых знаков19 серебряных знаков50 бронзовых знаков
1
Начиная с python-3.8 в язык добавлен walrus operator :=
, использование которого может немного сократить объем кода в таких задачах, как в вопросе.
Также можно избежать явного сравнения с 0
, полагаясь на неявное приведение к bool
.
s = 0
while number := int(input("input: ")):
s += number
print(s)
ответ дан 7 дек 2020 в 8:28
user207200user207200
5,0908 золотых знаков23 серебряных знака41 бронзовый знак
Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Summing Values the Pythonic Way With sum()
Python’s built-in function sum()
is an efficient and Pythonic way to sum a list of numeric values. Adding several numbers together is a common intermediate step in many computations, so sum()
is a pretty handy tool for a Python programmer.
As an additional and interesting use case, you can concatenate lists and tuples using sum()
, which can be convenient when you need to flatten a list of lists.
In this tutorial, you’ll learn how to:
- Sum numeric values by hand using general techniques and tools
- Use Python’s
sum()
to add several numeric values efficiently - Concatenate lists and tuples with
sum()
- Use
sum()
to approach common summation problems - Use appropriate values for the arguments in
sum()
- Decide between
sum()
and alternative tools to sum and concatenate objects
This knowledge will help you efficiently approach and solve summation problems in your code using either sum()
or other alternative and specialized tools.
Understanding the Summation Problem
Summing numeric values together is a fairly common problem in programming. For example, say you have a list of numbers [1, 2, 3, 4, 5] and want to add them together to compute their total sum. With standard arithmetic, you’ll do something like this:
1 + 2 + 3 + 4 + 5 = 15
As far as math goes, this expression is pretty straightforward. It walks you through a short series of additions until you find the sum of all the numbers.
It’s possible to do this particular calculation by hand, but imagine some other situations where it might not be so possible. If you have a particularly long list of numbers, adding by hand can be inefficient and error-prone. What happens if you don’t even know how many items are in the list? Finally, imagine a scenario where the number of items you need to add changes dynamically or unpredictably.
In situations like these, whether you have a long or short list of numbers, Python can be quite useful to solve summation problems.
If you want to sum the numbers by creating your own solution from scratch, then you can try using a for
loop:
>>>
>>> numbers = [1, 2, 3, 4, 5]
>>> total = 0
>>> for number in numbers:
... total += number
...
>>> total
15
Here, you first create total
and initialize it to 0
. This variable works as an accumulator in which you store intermediate results until you get the final one. The loop iterates through numbers
and updates total
by accumulating each successive value using an augmented assignment.
You can also wrap the for
loop in a function. This way, you can reuse the code for different lists:
>>>
>>> def sum_numbers(numbers):
... total = 0
... for number in numbers:
... total += number
... return total
...
>>> sum_numbers([1, 2, 3, 4, 5])
15
>>> sum_numbers([])
0
In sum_numbers()
, you take an iterable—specifically, a list of numeric values—as an argument and return the total sum of the values in the input list. If the input list is empty, then the function returns 0
. The for
loop is the same one that you saw before.
You can also use recursion instead of iteration. Recursion is a functional programming technique where a function is called within its own definition. In other words, a recursive function calls itself in a loop:
>>>
>>> def sum_numbers(numbers):
... if len(numbers) == 0:
... return 0
... return numbers[0] + sum_numbers(numbers[1:])
...
>>> sum_numbers([1, 2, 3, 4, 5])
15
When you define a recursive function, you take the risk of running into an infinite loop. To prevent this, you need to define both a base case that stops the recursion and a recursive case to call the function and start the implicit loop.
In the above example, the base case implies that the sum of a zero-length list is 0
. The recursive case implies that the total sum is the first value, numbers[0]
, plus the sum of the rest of the values, numbers[1:]
. Because the recursive case uses a shorter sequence on each iteration, you expect to run into the base case when numbers
is a zero-length list. As a final result, you get the sum of all the items in your input list, numbers
.
Another option to sum a list of numbers in Python is to use reduce()
from functools
. To get the sum of a list of numbers, you can pass either operator.add
or an appropriate lambda
function as the first argument to reduce()
:
>>>
>>> from functools import reduce
>>> from operator import add
>>> reduce(add, [1, 2, 3, 4, 5])
15
>>> reduce(add, [])
Traceback (most recent call last):
...
TypeError: reduce() of empty sequence with no initial value
>>> reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
15
You can call reduce()
with a reduction, or folding, function
along with an iterable
as arguments. Then reduce()
uses the input function to process iterable
and returns a single cumulative value.
In the first example, the reduction function is add()
, which takes two numbers and adds them together. The final result is the sum of the numbers in the input iterable
. As a drawback, reduce()
raises a TypeError
when you call it with an empty iterable
.
In the second example, the reduction function is a lambda
function that returns the addition of two numbers.
Since summations like these are commonplace in programming, coding a new function every time you need to sum some numbers is a lot of repetitive work. Additionally, using reduce()
isn’t the most readable solution available to you.
Python provides a dedicated built-in function to solve this problem. The function is conveniently called sum()
. Since it’s a built-in function, you can use it directly in your code without importing anything.
Getting Started With Python’s sum()
Readability is one of the most important principles behind Python’s philosophy. Visualize what you are asking a loop to do when summing a list of values. You want it to loop over some numbers, accumulate them in an intermediate variable, and return the final sum. However, you can probably imagine a more readable version of summation that doesn’t need a loop. You want Python to take some numbers and sum them together.
Now think about how reduce()
does summation. Using reduce()
is arguably less readable and less straightforward than even the loop-based solution.
This is why Python 2.3 added sum()
as a built-in function to provide a Pythonic solution to the summation problem. Alex Martelli contributed the function, which nowadays is the preferred syntax for summing a list of values:
>>>
>>> sum([1, 2, 3, 4, 5])
15
>>> sum([])
0
Wow! That’s neat, isn’t it? It reads like plain English and clearly communicates the action you’re performing on the input list. Using sum()
is way more readable than a for
loop or a reduce()
call. Unlike reduce()
, sum()
doesn’t raise a TypeError
when you provide an empty iterable. Instead, it understandably returns 0
.
You can call sum()
with the following two arguments:
iterable
is a required argument that can hold any Python iterable. The iterable typically contains numeric values but can also contain lists or tuples.start
is an optional argument that can hold an initial value. This value is then added to the final result. It defaults to0
.
Internally, sum()
adds start
plus the values in iterable
from left to right. The values in the input iterable
are normally numbers, but you can also use lists and tuples. The optional argument start
can accept a number, list, or tuple, depending on what is passed to iterable
. It can’t take a string.
In the following two sections, you’ll learn the basics of using sum()
in your code.
The Required Argument: iterable
Accepting any Python iterable as its first argument makes sum()
generic, reusable, and polymorphic. Because of this feature, you can use sum()
with lists, tuples, sets, range
objects, and dictionaries:
>>>
>>> # Use a list
>>> sum([1, 2, 3, 4, 5])
15
>>> # Use a tuple
>>> sum((1, 2, 3, 4, 5))
15
>>> # Use a set
>>> sum({1, 2, 3, 4, 5})
15
>>> # Use a range
>>> sum(range(1, 6))
15
>>> # Use a dictionary
>>> sum({1: "one", 2: "two", 3: "three"})
6
>>> sum({1: "one", 2: "two", 3: "three"}.keys())
6
In all these examples, sum()
computes the arithmetic sum of all the values in the input iterable regardless of their types. In the two dictionary examples, both calls to sum()
return the sum of the keys of the input dictionary. The first example sums the keys by default and the second example sums the keys because of the .keys()
call on the input dictionary.
If your dictionary stores numbers in its values and you would like to sum these values instead of the keys, then you can do this by using .values()
just like in the .keys()
example.
You can also use sum()
with a list comprehension as an argument. Here’s an example that computes the sum of the squares of a range of values:
>>>
>>> sum([x ** 2 for x in range(1, 6)])
55
Python 2.4 added generator expressions to the language. Again, sum()
works as expected when you use a generator expression as an argument:
>>>
>>> sum(x ** 2 for x in range(1, 6))
55
This example shows one of the most Pythonic techniques to approach the summation problem. It provides an elegant, readable, and efficient solution in a single line of code.
The Optional Argument: start
The second and optional argument, start
, allows you to provide a value to initialize the summation process. This argument is handy when you need to process cumulative values sequentially:
>>>
>>> sum([1, 2, 3, 4, 5], 100) # Positional argument
115
>>> sum([1, 2, 3, 4, 5], start=100) # Keyword argument
115
Here, you provide an initial value of 100
to start
. The net effect is that sum()
adds this value to the cumulative sum of the values in the input iterable. Note that you can provide start
as a positional argument or as a keyword argument. The latter option is way more explicit and readable.
If you don’t provide a value to start
, then it defaults to 0
. A default value of 0
ensures the expected behavior of returning the total sum of the input values.
Summing Numeric Values
The primary purpose of sum()
is to provide a Pythonic way to add numeric values together. Up to this point, you’ve seen how to use the function to sum integer numbers. Additionally, you can use sum()
with any other numeric Python types, such as float
, complex
, decimal.Decimal
, and fractions.Fraction
.
Here are a few examples of using sum()
with values of different numeric types:
>>>
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> # Sum floating-point numbers
>>> sum([10.2, 12.5, 11.8])
34.5
>>> sum([10.2, 12.5, 11.8, float("inf")])
inf
>>> sum([10.2, 12.5, 11.8, float("nan")])
nan
>>> # Sum complex numbers
>>> sum([3 + 2j, 5 + 6j])
(8+8j)
>>> # Sum Decimal numbers
>>> sum([Decimal("10.2"), Decimal("12.5"), Decimal("11.8")])
Decimal('34.5')
>>> # Sum Fraction numbers
>>> sum([Fraction(51, 5), Fraction(25, 2), Fraction(59, 5)])
Fraction(69, 2)
Here, you first use sum()
with floating-point numbers. It’s worth noting the function’s behavior when you use the special symbols inf
and nan
in the calls float("inf")
and float("nan")
. The first symbol represents an infinite value, so sum()
returns inf
. The second symbol represents NaN (not a number) values. Since you can’t add numbers with non-numbers, you get nan
as a result.
The other examples sum iterables of complex
, Decimal
, and Fraction
numbers. In all cases, sum()
returns the resulting cumulative sum using the appropriate numeric type.
Concatenating Sequences
Even though sum()
is mostly intended to operate on numeric values, you can also use the function to concatenate sequences such as lists and tuples. To do that, you need to provide an appropriate value to start
:
>>>
>>> num_lists = [[1, 2, 3], [4, 5, 6]]
>>> sum(num_lists, start=[])
[1, 2, 3, 4, 5, 6]
>>> # Equivalent concatenation
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> num_tuples = ((1, 2, 3), (4, 5, 6))
>>> sum(num_tuples, start=())
(1, 2, 3, 4, 5, 6)
>>> # Equivalent concatenation
>>> (1, 2, 3) + (4, 5, 6)
(1, 2, 3, 4, 5, 6)
In these examples, you use sum()
to concatenate lists and tuples. This is an interesting feature that you can use to flatten a list of lists or a tuple of tuples. The key requirement for these examples to work is to select an appropriate value for start
. For example, if you want to concatenate lists, then start
needs to hold a list.
In the examples above, sum()
is internally performing a concatenation operation, so it works only with those sequence types that support concatenation, with the exception of strings:
>>>
>>> num_strs = ["123", "456"]
>>> sum(num_strs, "0")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]
When you try to use sum()
to concatenate strings, you get a TypeError
. As the exception message suggests, you should use str.join()
to concatenate strings in Python. You’ll see examples of using this method later on when you get to the section on Using Alternatives to sum()
.
Practicing With Python’s sum()
So far, you’ve learned the basics of working with sum()
. You’ve learned how to use this function to add numeric values together and also to concatenate sequences such as lists and tuples.
In this section, you’ll look at some more examples of when and how to use sum()
in your code. With these practical examples, you’ll learn that this built-in function is quite handy when you’re performing computations that require finding the sum of a series of numbers as an intermediate step.
You’ll also learn that sum()
can be helpful when you’re working with lists and tuples. A special example you’ll look at is when you need to flatten a list of lists.
Computing Cumulative Sums
The first example you’ll code has to do with how to take advantage of the start
argument for summing cumulative lists of numeric values.
Say you’re developing a system to manage the sales of a given product at several different points of sale. Every day, you get a sold units report from each point of sale. You need to systematically compute the cumulative sum to know how many units the whole company sold over the week. To solve this problem, you can use sum()
:
>>>
>>> cumulative_sales = 0
>>> monday = [50, 27, 42]
>>> cumulative_sales = sum(monday, start=cumulative_sales)
>>> cumulative_sales
119
>>> tuesday = [12, 32, 15]
>>> cumulative_sales = sum(tuesday, start=cumulative_sales)
>>> cumulative_sales
178
>>> wednesday = [20, 24, 42]
>>> cumulative_sales = sum(wednesday, start=cumulative_sales)
>>> cumulative_sales
264
...
By using start
, you set an initial value to initialize the sum, which allows you to add successive units to the previously computed subtotal. At the end of the week, you’ll have the company’s total count of sold units.
Calculating the Mean of a Sample
Another practical use case of sum()
is to use it as an intermediate calculation before doing further calculations. For example, say you need to calculate the arithmetic mean of a sample of numeric values. The arithmetic mean, also known as the average, is the total sum of the values divided by the number of values, or data points, in the sample.
If you have the sample [2, 3, 4, 2, 3, 6, 4, 2] and you want to calculate the arithmetic mean by hand, then you can solve this operation:
(2 + 3 + 4 + 2 + 3 + 6 + 4 + 2) / 8 = 3.25
If you want to speed this up by using Python, you can break it up into two parts. The first part of this computation, where you are adding together the numbers, is a task for sum()
. The next part of the operation, where you are dividing by 8, uses the count of numbers in your sample. To calculate your divisor, you can use len()
:
>>>
>>> data_points = [2, 3, 4, 2, 3, 6, 4, 2]
>>> sum(data_points) / len(data_points)
3.25
Here, the call to sum()
computes the total sum of the data points in your sample. Next, you use len()
to get the number of data points. Finally, you perform the required division to calculate the sample’s arithmetic mean.
In practice, you may want to turn this code into a function with some additional features, such as a descriptive name and a check for empty samples:
>>>
>>> # Python >= 3.8
>>> def average(data_points):
... if (num_points := len(data_points)) == 0:
... raise ValueError("average requires at least one data point")
... return sum(data_points) / num_points
...
>>> average([2, 3, 4, 2, 3, 6, 4, 2])
3.25
>>> average([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in average
ValueError: average requires at least one data point
Inside average()
, you first check if the input sample has any data points. If not, then you raise a ValueError
with a descriptive message. In this example, you use the walrus operator to store the number of data points in the variable num_points
so that you won’t need to call len()
again. The return statement computes the sample’s arithmetic mean and sends it back to the calling code.
Note that when you call average()
with a proper sample, you’ll get the desired mean. If you call average()
with an empty sample, then you get a ValueError
as expected.
Finding the Dot Product of Two Sequences
Another problem you can solve using sum()
is finding the dot product of two equal-length sequences of numeric values. The dot product is the algebraic sum of products of every pair of values in the input sequences. For example, if you have the sequences (1, 2, 3) and (4, 5, 6), then you can calculate their dot product by hand using addition and multiplication:
1 × 4 + 2 × 5 + 3 × 6 = 32
To extract successive pairs of values from the input sequences, you can use zip()
. Then you can use a generator expression to multiply each pair of values. Finally, sum()
can sum the products:
>>>
>>> x_vector = (1, 2, 3)
>>> y_vector = (4, 5, 6)
>>> sum(x * y for x, y in zip(x_vector, y_vector))
32
With zip()
, you generate a list of tuples with the values from each of the input sequences. The generator expression loops over each tuple while multiplying the successive pairs of values previously arranged by zip()
. The final step is to add the products together using sum()
.
The code in the above example works. However, the dot product is defined for sequences of equal length, so what happens if you provide sequences with different lengths? In that case, zip()
ignores the extra values from the longest sequence, which leads to an incorrect result.
To deal with this possibility, you can wrap the call to sum()
in a custom function and provide a proper check for the length of the input sequences:
>>>
>>> def dot_product(x_vector, y_vector):
... if len(x_vector) != len(y_vector):
... raise ValueError("Vectors must have equal sizes")
... return sum(x * y for x, y in zip(x_vector, y_vector))
...
>>> dot_product((1, 2, 3), (4, 5, 6))
32
>>> dot_product((1, 2, 3, 4), (5, 6, 3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in dot_product
ValueError: Vectors must have equal sizes
Here, dot_product()
takes two sequences as arguments and returns their corresponding dot product. If the input sequences have different lengths, then the function raises a ValueError
.
Embedding the functionality in a custom function allows you to reuse the code. It also gives you the opportunity to name the function descriptively so that the user knows what the function does just by reading its name.
Flattening a List of Lists
Flattening a list of lists is a common task in Python. Say you have a list of lists and need to flatten it into a single list containing all the items from the original nested lists. You can use any of several approaches to flattening lists in Python. For example, you can use a for
loop, as in the following code:
>>>
>>> def flatten_list(a_list):
... flat = []
... for sublist in a_list:
... flat += sublist
... return flat
...
>>> matrix = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>> flatten_list(matrix)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Inside flatten_list()
, the loop iterates over all the nested lists contained in a_list
. Then it concatenates them in flat
using an augmented assignment operation (+=
). As the result, you get a flat list with all the items from the original nested lists.
But hold on! You’ve already learned how to use sum()
to concatenate sequences in this tutorial. Can you use that feature to flatten a list of lists like you did in the example above? Yes! Here’s how:
>>>
>>> matrix = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>> sum(matrix, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
That was quick! A single line of code and matrix
is now a flat list. However, using sum()
doesn’t seem to be the fastest solution.
An important drawback of any solution that implies concatenation is that behind the scenes, every intermediate step creates a new list. This can be pretty wasteful in terms of memory usage. The list that is eventually returned is just the most recently created list out of all the lists that were created at each round of concatenation. Using a list comprehension instead ensures that you create and return only one list:
>>>
>>> def flatten_list(a_list):
... return [item for sublist in a_list for item in sublist]
...
>>> matrix = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>> flatten_list(matrix)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
This new version of flatten_list()
is more efficient and less wasteful in terms of memory usage. However, the nested comprehensions can be challenging to read and understand.
Using .append()
is probably the most readable and Pythonic way to flatten a list of lists:
>>>
>>> def flatten_list(a_list):
... flat = []
... for sublist in a_list:
... for item in sublist:
... flat.append(item)
... return flat
...
>>> matrix = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>> flatten_list(matrix)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
In this version of flatten_list()
, someone reading your code can see that the function iterates over every sublist
in a_list
. Inside this first for
loop, it iterates over each item
in sublist
to finally populate the new flat
list with .append()
. Just like the comprehension from earlier, this solution creates only one list in the process. An advantage of this solution is that it is very readable.
Using Alternatives to sum()
As you’ve already learned, sum()
is helpful for working with numeric values in general. However, when it comes to working with floating-point numbers, Python provides an alternative tool. In math
, you’ll find a function called fsum()
that can help you improve the general precision of your floating-point computations.
You might have a task where you want to concatenate or chain several iterables so that you can work with them as one. For this scenario, you can look to the itertools
module’s function chain()
.
You might also have a task where you want to concatenate a list of strings. You’ve learned in this tutorial that there’s no way to use sum()
for concatenating strings. This function just wasn’t built for string concatenation. The most Pythonic alternative is to use str.join()
.
Summing Floating-Point Numbers: math.fsum()
If your code is constantly summing floating-point numbers with sum()
, then you should consider using math.fsum()
instead. This function performs floating-point computations more carefully than sum()
, which improves the precision of your computation.
According to its documentation, fsum()
“avoids loss of precision by tracking multiple intermediate partial sums.” The documentation provides the following example:
>>>
>>> from math import fsum
>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
0.9999999999999999
>>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
1.0
With fsum()
, you get a more precise result. However, you should note that fsum()
doesn’t solve the representation error in floating-point arithmetic. The following example uncovers this limitation:
>>>
>>> from math import fsum
>>> sum([0.1, 0.2])
0.30000000000000004
>>> fsum([0.1, 0.2])
0.30000000000000004
In these examples, both functions return the same result. This is due to the impossibility of accurately representing both values 0.1
and 0.2
in binary floating-point:
>>>
>>> f"{0.1:.28f}"
'0.1000000000000000055511151231'
>>> f"{0.2:.28f}"
'0.2000000000000000111022302463'
Unlike sum()
, however, fsum()
can help you reduce floating-point error propagation when you add very large and very small numbers together:
>>>
>>> from math import fsum
>>> sum([1e-16, 1, 1e16])
1e+16
>>> fsum([1e-16, 1, 1e16])
1.0000000000000002e+16
>>> sum([1, 1, 1e100, -1e100] * 10_000)
0.0
>>> fsum([1, 1, 1e100, -1e100] * 10_000)
20000.0
Wow! The second example is pretty surprising and totally defeats sum()
. With sum()
, you get 0.0
as a result. This is quite far away from the correct result of 20000.0
, as you get with fsum()
.
Concatenating Iterables With itertools.chain()
If you’re looking for a handy tool for concatenating or chaining a series of iterables, then consider using chain()
from itertools
. This function can take multiple iterables and build an iterator that yields items from the first one, from the second one, and so on until it exhausts all the input iterables:
>>>
>>> from itertools import chain
>>> numbers = chain([1, 2, 3], [4, 5, 6], [7, 8, 9])
>>> numbers
<itertools.chain object at 0x7f0d0f160a30>
>>> next(numbers)
1
>>> next(numbers)
2
>>> list(chain([1, 2, 3], [4, 5, 6], [7, 8, 9]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
When you call chain()
, you get an iterator of the items from the input iterables. In this example, you access successive items from numbers
using next()
. If you want to work with a list instead, then you can use list()
to consume the iterator and return a regular Python list.
chain()
is also a good option for flattening a list of lists in Python:
>>>
>>> from itertools import chain
>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> list(chain(*matrix))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
To flatten a list of lists with chain()
, you need to use the iterable unpacking operator (*
). This operator unpacks all the input iterables so that chain()
can work with them and generate the corresponding iterator. The final step is to call list()
to build the desired flat list.
Concatenating Strings With str.join()
As you’ve already seen, sum()
doesn’t concatenate or join strings. If you need to do so, then the preferred and fastest tool available in Python is str.join()
. This method takes a sequence of strings as an argument and returns a new, concatenated string:
>>>
>>> greeting = ["Hello,", "welcome to", "Real Python!"]
>>> " ".join(greeting)
'Hello, welcome to Real Python!'
Using .join()
is the most efficient and Pythonic way to concatenate strings. Here, you use a list of strings as an argument and build a single string from the input. Note that .join()
uses the string on which you call the method as a separator during the concatenation. In this example, you call .join()
on a string that consists of a single space character (" "
), so the original strings from greeting
are separated by spaces in your final string.
Conclusion
You can now use Python’s built-in function sum()
to add multiple numeric values together. This function provides an efficient, readable, and Pythonic way to solve summation problems in your code. If you’re dealing with math computations that require summing numeric values, then sum()
can be your lifesaver.
In this tutorial, you learned how to:
- Sum numeric values using general techniques and tools
- Add several numeric values efficiently using Python’s
sum()
- Concatenate sequences using
sum()
- Use
sum()
to approach common summation problems - Use appropriate values for the
iterable
andstart
arguments insum()
- Decide between
sum()
and alternative tools to sum and concatenate objects
With this knowledge, you’re now able to add multiple numeric values together in a Pythonic, readable, and efficient way.
Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Summing Values the Pythonic Way With sum()
В данной статье мы расскажем, как на Python вычисляется сумма и среднее значение первых n
натуральных чисел. Кроме того, мы разберем, как найти сумму чисел, введённых пользователем, и их среднее значение. Также мы рассмотрим встроенную функцию sum()
и вычисление среднего значения списка чисел.
Содержание
- Сумма и среднее значение первых n натуральных чисел
- Встроенная функция
sum()
- Встроенная функция
- Сумма и среднее значение списка чисел
- Вычисление суммы и среднего значения при помощи математической формулы
- Сумма и среднее значение чисел, введенных пользователем
- Использование цикла while для вычисления суммы и среднего значения
- Практическая задача: сложение двух матриц в Python
Алгоритм решения данной задачи:
- Принимаем значение числа
n
от пользователя. Для этого используется функцияinput()
. - Затем запустим цикл
for
до введенного числа, используя для этого функциюrange()
. На каждой итерации мы будем получать следующее число, пока цикл не достигнет последнего числа, то есть n. - Вычислим сумму всех этих чисел. Для этого на каждой итерации цикла будем добавлять число к переменной
sum
. - И наконец, после завершения цикла вычислим среднее значение по формуле:
average = sum / n
, гдеn
– это число, введенное пользователем.
Код программы:
n = int(input("Enter number")) sum = 0 # Цикл от 1 до n for num in range(1, n + 1, 1): sum = sum + num print("Sum of first ", n, "numbers is: ", sum) average = sum / n print("Average of ", n, "numbers is: ", average)
Результат:
Enter number 10 Sum of first 10 numbers is: 55 Average of 10 numbers is: 5.5
Встроенная функция sum()
Для вычисления суммы элементов итерируемых объектов, таких как список или функция range()
, можно также воспользоваться встроенной функцией sum()
.
n = 10 res = sum(range(1, n + 1)) print("Sum of first ", n, "numbers is: ", res) # Результат: # Sum of first 10 numbers is: 55
Сумма и среднее значение списка чисел
Для вычисления суммы всех чисел списка и их среднего значения нужно сделать следующее:
- Проитерировать список при помощи цикла
for
и прибавить каждое число к переменнойsum
. - Для вычисления среднего значения разделить полученную сумму на число элементов списка (его длину, вычисляемую при помощи встроенной функции
len()
).
# Список со значениями int и float num_list = [10, 20.5, 30, 45.5, 50] # Первый подход, с использованием встроенной функции sum res = sum(num_list) avg = res / len(num_list) print("sum is: ", res, "Average is: ", avg) # Результат: # sum is: 156.0 Average is: 31.2 # Второй подход, с использованием цикла for res1 = 0 for num in num_list: res1 += num avg1 = res1 / len(num_list) print("sum is: ", res1, "Average is: ", avg1) # Результат: # sum is: 156.0 Average is: 31.2
Вычисление суммы и среднего значения при помощи математической формулы
В приведенных выше программах мы вычисляли сумму и среднее при помощи циклов. Теперь давайте посмотрим, как рассчитать сумму и среднее значение напрямую, используя математическую формулу суммы арифметической прогрессии.
Пусть n
это последнее число нашей последовательности первых n
натуральных чисел. Тогда:
- сумма n натуральных чисел будет равна
n * (n+1) / 2
- а их среднее значение –
(n * (n+1) / 2) / n
Пример:
n = 20 # Формула для вычисления суммы res = n * (n + 1) / 2 print('sum of first', n, 'numbers is:', res) # Результат: # sum of first 20 numbers is: 210.0 # Формула для вычисления среднего average = (n * (n + 1) / 2) / n print('Average of first', n, 'numbers is:', average) # Результат: # Average of 20 numbers is: 10.5
Сумма и средние значение нескольких чисел, введённых пользователем
А вот как можно рассчитать сумму и среднее значение нескольких введённых пользователем чисел:
input_string = input('Enter numbers separated by space ') print("n") # Преобразуем введённые числа в список numbers = input_string.split() # Приводим числа к типу int for i in range(len(numbers)): numbers[i] = int(numbers[i]) # Вычисляем сумму и среднее значение print("Sum = ", sum(numbers)) print("Average = ", sum(numbers) / len(numbers))
Результат:
Enter numbers separated by space 10 20 30 40 50 Sum = 150 Average = 30.0
Использование цикла while
для вычисления суммы и среднего значения
Для вычисления суммы первых n
чисел и их среднего значения также можно использовать цикл while
.
Вот возможный алгоритм:
- Определяем число
n
- Запускаем цикл
while
до тех пор, покаn
будет больше 0 - В каждой итерации добавляем текущее значение
n
к переменнойsum
и уменьшаемn
на 1 - Вычисляем среднее значение, разделив сумму на
n
n = 20 total_numbers = n sum = 0 while n >= 0: sum += n n -= 1 print("sum =", sum) # Результат # sum = 210 average = sum / total_numbers print("Average = ", average) # Результат: # Average = 10.5
Практическая задача: сложение двух матриц в Python
matrixOne = [[6,9,11], [2 ,3,8]] matrixTwo = [[15,18,11], [26,16,19]] # Инициализируем нулями матрицу, в которую будет сохранен результат result = [[0,0,0], [0,0,0]]
Решение данной задачи:
matrixOne = [[6,9,11], [2 ,3,8]] matrixTwo = [[15,18,11], [26,16,19]] result = [[0,0,0], [0,0,0]] # Сначала перебираем строки for i in range(len(matrixOne)): # Затем перебираем столбцы for j in range(len(matrixOne[0])): result[i][j] = matrixOne[i][j] + matrixTwo[i][j] print("Addition of two Matrix In Python") for res in result: print(*res)
Результат:
Addition of two Matrix In Python 21 27 22 28 19 27
Перевод статьи “Python program to calculate sum and average of first n natural numbers”.
На чтение 4 мин Просмотров 3.7к. Опубликовано
Python — это язык программирования, который предоставляет нам различные встроенные функции и методы для работы со списками. Одной из таких операций является нахождение суммы чисел в списке. Это может быть полезным, когда необходимо произвести анализ числовых данных, например, при подсчете среднего значения или нахождении суммы элементов, удовлетворяющих определенным условиям. В этой статье мы рассмотрим различные методы нахождения суммы чисел в списке Python.
Содержание
- Методы для нахождения суммы чисел в списке
- Использование цикла for
- Использование встроенной функции sum()
- Использование рекурсии
- Обработка исключений при нахождении суммы чисел в списке
Методы для нахождения суммы чисел в списке
Использование цикла for
Цикл for
является одним из наиболее простых и часто используемых способов для нахождения суммы чисел в списке. Просто пройдитесь по каждому элементу списка и добавьте его к накопленной сумме.
Вот пример кода, который демонстрирует использование цикла for
для нахождения суммы чисел в списке:
numbers = [1, 2, 3, 4, 5]
total = 0
for num in numbers:
total += num
print("Сумма чисел в списке: ", total)
В этом примере мы создали список чисел от 1 до 5 и присвоили его переменной numbers
. Затем мы создали переменную total
и присвоили ей начальное значение 0. Затем мы проходим по каждому элементу списка numbers
и добавляем его к переменной total
. Наконец, мы выводим сумму чисел на экран.
Важно отметить, что мы должны инициализировать переменную total
нулевым значением перед выполнением цикла, чтобы иметь место, куда добавлять числа. Если мы попытаемся добавить число к неинициализированной переменной, возникнет ошибка.
Цикл for
также может использоваться для нахождения суммы чисел в многомерном списке. В этом случае нам нужно будет использовать вложенный цикл for
, чтобы перебрать каждый элемент списка.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
total = 0
for row in matrix:
for num in row:
total += num
print("Сумма чисел в многомерном списке: ", total)
В этом примере мы создали многомерный список, содержащий три списка с числами. Затем мы создали переменную total
и присвоили ей начальное значение 0. Затем мы используем два вложенных цикла for
для перебора каждого элемента списка и добавления его к переменной total
. Наконец, мы выводим сумму чисел на экран.
Использование встроенной функции sum()
Использование встроенной функции sum()
для нахождения суммы чисел в списке является очень простым и эффективным способом. Функция sum()
принимает один аргумент — итерируемый объект, такой как список, и возвращает сумму всех элементов в нем.
Простой пример использования функции sum()
для нахождения суммы всех чисел в списке:
my_list = [1, 2, 3, 4, 5]
sum_of_list = sum(my_list)
print(sum_of_list)
Важно отметить, что функция sum()
может работать только с итерируемыми объектами, элементы которых могут быть сложены. Если элементы списка не могут быть сложены, будет возбуждено исключение типа TypeError
.
Использование рекурсии
Использование рекурсии — это еще один способ нахождения суммы чисел в списке Python. Рекурсия — это процесс вызова функцией самой себя. Для нахождения суммы чисел в списке при помощи рекурсии, необходимо реализовать функцию, которая будет вызывать саму себя до тех пор, пока не достигнет базового случая.
Пример реализации функции для нахождения суммы чисел в списке при помощи рекурсии:
numbers = [1, 2, 3, 4, 5]
result = recursive_sum(numbers)
print(result)
Здесь мы определяем функцию recursive_sum
, которая принимает список чисел numbers
. Если в списке остается только один элемент, то возвращаем его значение. В противном случае мы возвращаем сумму первого элемента списка и рекурсивного вызова функции для оставшейся части списка.
Хотя использование рекурсии для нахождения суммы чисел в списке может быть удобным и понятным, стоит иметь в виду, что это может привести к переполнению стека вызовов функций при больших списках. Поэтому, в большинстве случаев лучше использовать более эффективные методы, такие как использование встроенной функции sum()
или цикла for
.
Обработка исключений при нахождении суммы чисел в списке
При работе с данными, особенно с пользовательским вводом, всегда есть вероятность получения ошибочных данных. Для обработки ошибок при нахождении суммы чисел в списке можно использовать конструкцию try-except.
При использовании описанных выше методов для нахождения суммы чисел в списке возможны следующие ошибки:
- TypeError — возникает, если элемент списка не является числом.
- ValueError — возникает, если в списке есть пустые строки или нечисловые значения.
Для обработки этих ошибок можно использовать конструкцию try-except. Например, чтобы обработать ошибку TypeError, мы можем использовать следующий код:
numbers = [1, 2, 3, '4', 5]
total = 0
for num in numbers:
try:
total += num
except TypeError:
print(f"Элемент {num} не является числом")
print(f"Сумма чисел в списке: {total}")
В результате выполнения данного кода мы получим следующий вывод:
Элемент 4 не является числом
Сумма чисел в списке: 11
Обработка ошибок позволяет избежать прерывания работы программы при возникновении ошибок и предоставляет возможность корректно обработать их в процессе выполнения программы.
Задачи по функции sum() и решения к ним у нас в телеграм канале PythonTurbo
Давайте разберем, что такое функция sum() в Python и почему это питонический способ суммирования.
Встроенная функция sum() – это эффективный и питонический способ суммирования списка числовых значений. Сложение нескольких чисел является обычным промежуточным шагом во многих вычислениях, поэтому sum()
– довольно удобный инструмент для программиста Python.
Еще с помощью sum()
можно объединять списки и кортежи. Это интересный дополнительный вариант использования, полезный, когда вам нужно сгладить список списков.
Приведенная ниже информация поможет вам эффективно решать проблемы суммирования в вашем коде с помощью sum()
или других альтернативных и специализированных инструментов.
Понимание проблемы суммирования
Суммирование числовых значений – довольно распространенная задача в программировании. Например, предположим, что у вас есть список чисел a = [1, 2, 3, 4, 5]
и вы хотите сложить элементы и получить сумму. Используя стандартную арифметику, вы сделаете что-то вроде этого:
1 + 2 + 3 + 4 + 5 = 15
Что касается математики, это выражение довольно простое.
Можно выполнить этот конкретный расчет вручную, но представьте себе другие ситуации, в которых это может быть невозможно. Если у вас очень длинный список чисел, добавление вручную будет неэффективным и, скорее всего, вы допустите ошибку. А если вы даже не знаете, сколько элементов в списке? Наконец, представьте сценарий, в котором количество элементов, которые вам нужно добавить, изменяется динамически или вообще непредсказуемо.
В подобных ситуациях, независимо от того, есть ли у вас длинный или короткий список чисел, Python может быть весьма полезен для решения задач суммирования.
Использование цикла for
Если вы хотите суммировать числа, создав собственное решение с нуля, вы можете использовать цикл for
:
numbers = [1, 2, 3, 4, 5] total = 0 for number in numbers: total += number print(total) # 15
Здесь вы сначала инициализируете сумму и приравниваете её к 0. Эта переменная работает как аккумулятор, в котором вы сохраняете промежуточные результаты, пока не получите окончательный. Цикл перебирает числа и обновляет общее количество.
Цикл for
можно заключить в функцию. Благодаря этому вы сможете повторно использовать код для разных списков:
def sum_numbers(numbers): total = 0 for number in numbers: total += number return total sum_numbers([1, 2, 3, 4, 5]) # 15 sum_numbers([]) # 0
В sum_numbers()
вы берете итерируемый объект в качестве аргумента и возвращаете общую сумму значений элементов списка.
Прямо сейчас можете попробовать решить задачку «Напишите программу на Python для суммирования всех элементов в списке»
def sum_list(items): ваш код print(sum_list([1, 2, -8])) #В выводе должно быть -5
Условие и решение есть в наших поста тут и тут
Использование рекурсии
Вы также можете использовать рекурсию вместо итерации. Рекурсия – это метод функционального программирования, при котором функция вызывается в пределах ее собственного определения. Другими словами, рекурсивная функция вызывает сама себя в цикле:
def sum_numbers(numbers): if len(numbers) == 0: return 0 return numbers[0] + sum_numbers(numbers[1:]) sum_numbers([1, 2, 3, 4, 5]) # 15
Когда вы определяете рекурсивную функцию, вы рискуете попасть в бесконечный цикл. Чтобы предотвратить это, нужно определить как базовый случай, останавливающий рекурсию, так и рекурсивный случай для вызова функции и запуска неявного цикла.
В приведенном выше примере базовый случай подразумевает, что сумма списка нулевой длины равна 0. Рекурсивный случай подразумевает, что общая сумма – это первый элемент плюс сумма остальных элементов. Поскольку рекурсивный случай использует более короткую последовательность на каждой итерации, вы ожидаете столкнуться с базовым случаем, когда числа представляют собой список нулевой длины.
[python_ad_block]
Использование reduce()
Другой вариант суммирования списка чисел в Python – использовать reduce()
из functools. Чтобы получить сумму списка чисел, вы можете передать либо оператор add
, либо соответствующую лямбда-функцию в качестве первого аргумента функции reduce()
:
from functools import reduce from operator import add reduce(add, [1, 2, 3, 4, 5]) # 15 reduce(add, []) # Traceback (most recent call last): # ... # TypeError: reduce() of empty sequence with no initial value reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]) # 15
Вы можете вызвать reduce()
с folding-функцией и итерируемым объектом в качестве аргументов. reduce()
использует переданную функцию для обработки итерируемого объекта и вернет единственное кумулятивное значение.
В первом примере folding-функция – это add()
, которая берет два числа и складывает их. Конечный результат – это сумма чисел во входном итерируемом объекте. Но если вы вызовете reduce()
с пустым итерируемым объектом, получите TypeError
.
Во втором примере folding-функция – это лямбда-функция, которая возвращает сложение двух чисел.
Поскольку суммирование является обычным явлением в программировании, писать новую функцию каждый раз, когда нам нужно сложить какие-нибудь числа, — бессмысленная работа. Кроме того, использование reduce()
– далеко не самое удобочитаемое решение.
Python предоставляет специальную встроенную функцию для решения этой проблемы. Это функция sum()
. Поскольку это встроенная функция, вы можете использовать ее в коде напрямую, ничего не импортируя.
В настоящее время функция sum() является предпочтительным способом для суммирования элементов:
sum([1, 2, 3, 4, 5]) # 15 sum([]) # 0
Здорово, не правда ли? Код читается как обычный текст и четко передает действие, которое вы выполняете. Использование sum()
значительно упрощает код. Более того, эта функция не вызывает TypeError
, если вы передали пустой список.
У sum()
есть два аргумента:
iterable
– обязательный аргумент, который может содержать любой итерируемый объект Python. Итерируемый объект обычно содержит числовые значения, но также может содержать списки или кортежи.start
– необязательный аргумент, который может содержать начальное значение. В конце суммирования элементов это значение добавляется к окончательному результату. По умолчанию равен 0.
Суммирование числовых значений
Основная цель sum()
– предоставить питонический способ сложения числовых значений. До этого момента вы видели, как использовать функцию для суммирования целых чисел. Кроме того, вы можете использовать sum()
с любыми другими числовыми типами Python, такими как float
, complex
, decimal.Decimal
и fractions.Fraction
.
Вот несколько примеров использования sum() со значениями разных числовых типов:
from decimal import Decimal from fractions import Fraction # Sum floating-point numbers sum([10.2, 12.5, 11.8]) # 34.5 sum([10.2, 12.5, 11.8, float("inf")]) # inf sum([10.2, 12.5, 11.8, float("nan")]) # nan # Sum complex numbers sum([3 + 2j, 5 + 6j]) # (8+8j) # Sum Decimal numbers sum([Decimal("10.2"), Decimal("12.5"), Decimal("11.8")]) # Decimal('34.5') # Sum Fraction numbers sum([Fraction(51, 5), Fraction(25, 2), Fraction(59, 5)]) # Fraction(69, 2)
Объединение последовательностей
Несмотря на то, что функция sum() в основном предназначена для работы с числовыми значениями, вы также можете использовать ее для объединения последовательностей, таких как списки и кортежи. Для этого вам нужно указать соответствующее значение для аргумента start
:
num_lists = [[1, 2, 3], [4, 5, 6]] sum(num_lists, start=[]) # [1, 2, 3, 4, 5, 6] # Equivalent concatenation [1, 2, 3] + [4, 5, 6] # [1, 2, 3, 4, 5, 6] num_tuples = ((1, 2, 3), (4, 5, 6)) sum(num_tuples, start=()) # (1, 2, 3, 4, 5, 6) # Equivalent concatenation (1, 2, 3) + (4, 5, 6) # (1, 2, 3, 4, 5, 6)
Ключевым требованием для работы этих примеров является выбор подходящего значения для start
. Например, если вы хотите объединить списки, то start
должен быть равен []
.
num_strs = ["123", "456"] sum(num_strs, "0") # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # TypeError: sum() can't sum strings [use ''.join(seq) instead]
Если же вы попытаетесь использовать sum()
для объединения строк, вы получите ошибку TypeError
. Она говорит нам о том, что для объединения строк в Python следует использовать str.join()
.
Примеры использования sum() в Python
До сих пор мы говорили про основы работы с sum()
. В этом разделе вы увидите еще несколько примеров того, когда и как использовать sum()
в вашем коде. Из этих практических примеров вы узнаете, что эта встроенная функция очень удобна, когда вы выполняете вычисления, требующие на промежуточном этапе нахождения суммы ряда чисел.
Кроме того, мы разберем, как применять sum()
при работе со списками и кортежами. Мы также рассмотрим особый пример, когда нужно объединить несколько списков.
Расчет среднего значения выборки
Один из практических вариантов применения sum()
– использовать ее в качестве промежуточного вычисления перед дальнейшими вычислениями. Например, вам нужно вычислить среднее арифметическое для выборки числовых значений. Среднее арифметическое, также известное как среднее значение, представляет собой общую сумму значений, деленную на количество значений в выборке.
Если у вас есть выборка [2, 3, 4, 2, 3, 6, 4, 2]
и вы хотите вычислить среднее арифметическое вручную, вы можете решить эту операцию так:
(2 + 3 + 4 + 2 + 3 + 6 + 4 + 2) / 8 = 3,25
Если вы хотите ускорить это с помощью Python, вы можете разбить решение на две части. Первая часть – вы складываете все числа – это задача для sum()
. В следующей части, где вы делите на 8, используется количество чисел в вашей выборке. Чтобы определить свой делитель, вы можете использовать len()
:
data_points = [2, 3, 4, 2, 3, 6, 4, 2] sum(data_points) / len(data_points) # 3.25
Здесь sum()
вычисляет общую сумму в нашей выборке. Затем мы используем len()
, чтобы получить общее количество. Наконец, выполняем деление, чтобы вычислить среднее арифметическое значение выборки.
Нахождение скалярного произведения двух последовательностей
Другая проблема, которую мы можем решить с помощью sum()
, – это нахождение скалярного произведения двух числовых последовательностей равной длины. Скалярное произведение – это алгебраическая сумма произведений каждой пары значений во входных последовательностях. Например, если у вас есть последовательности (1, 2, 3)
и (4, 5, 6)
, вы можете вычислить их скалярное произведение вручную, используя сложение и умножение:
1 × 4 + 2 × 5 + 3 × 6 = 32
Чтобы извлечь последовательные пары значений, мы можем использовать zip(). Затем воспользуемся генератором для умножения каждой пары значений. Наконец, sum()
поможет суммировать произведения:
x_vector = (1, 2, 3) y_vector = (4, 5, 6) sum(x * y for x, y in zip(x_vector, y_vector)) # 32
Объединение списков
Объединение списков – обычная задача в Python. Предположим, у вас есть список списков, и вам нужно объединить его в единый список, содержащий все элементы из исходных вложенных списков. Вы можете использовать любой из нескольких подходов к объединению списков в Python. Например, можно воспользоваться циклом for
, как в следующем коде:
def flatten_list(a_list): flat = [] for sublist in a_list: flat += sublist return flat matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] flatten_list(matrix) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Внутри flatten_list()
цикл перебирает все вложенные списки, содержащиеся в a_list
. Затем он объединяет их в один. В результате вы получаете единый список со всеми элементами из исходных вложенных списков.
Но можно ли использовать функцию sum()
для объединения списков, как в примере выше? Да! Вот как:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] sum(matrix, []) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Это было быстро! Одна строка кода — и мы получили единый список. Однако использование sum()
не кажется самым быстрым решением.
Важным недостатком любого решения, предполагающего конкатенацию, является то, что за кулисами каждый промежуточный шаг создает новый список. Это может быть довольно расточительным с точки зрения использования памяти.
Список, который в итоге возвращается, является самым последним созданным списком из всех, которые создавались на каждом этапе конкатенации. Использование генератора списка вместо этого гарантирует, что вы создадите и вернете только один список:
def flatten_list(a_list): return [item for sublist in a_list for item in sublist] matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] flatten_list(matrix) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Эта новая версия flatten_list()
более эффективна и менее расточительна с точки зрения использования памяти. Однако вложенные генераторы могут быть сложными для чтения и понимания.
Использование .append()
, вероятно, является наиболее читаемым и питоничным способом объединить списки:
def flatten_list(a_list): flat = [] for sublist in a_list: for item in sublist: flat.append(item) return flat matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] flatten_list(matrix) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
В этой версии функция выполняет итерацию по каждому подсписку в a_list
. Внутри внутреннего цикла for
она перебирает каждый элемент подсписка, чтобы заполнить новый список с помощью .append()
. Как и в предыдущем случае, это решение создает только один список в процессе. Преимущество его в том, что оно хорошо читается.
Альтернативы sum()
Как вы уже поняли, функция sum() полезна для работы с числовыми значениями в целом. Однако, когда дело доходит до работы с числами с плавающей запятой, Python предоставляет альтернативный инструмент. В библиотеке math
вы найдете функцию под названием fsum()
, которая поможет вам улучшить общую точность вычислений.
Вам может понадобиться объединить или связать несколько итерируемых объектов, чтобы работать с ними как с одним. Для этого можно использовать модуль itertools()
.
Также у вас может возникнуть необходимость объединить строки. Для этого нельзя использовать sum()
. Самая питоническая альтернатива – применить str.join()
.
Суммирование чисел с плавающей запятой: math.fsum()
Эта функция выполняет вычисления с плавающей запятой более тщательно, чем sum()
, что повышает точность.
Согласно документации, fsum()
«позволяет избежать потери точности, отслеживая несколько промежуточных частичных сумм». В документации приводится следующий пример:
from math import fsum sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) # 0.9999999999999999 fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) # 1.0
Используя fsum()
, вы получите более точный результат. Однако следует отметить, что fsum()
не устраняет ошибку представления в арифметике с плавающей запятой. Следующий пример раскрывает это ограничение:
from math import fsum sum([0.1, 0.2]) # 0.30000000000000004 fsum([0.1, 0.2]) # 0.30000000000000004
В этих примерах обе функции возвращают одинаковый результат. Это связано с невозможностью точного представления значений 0,1 и 0,2 в двоичной системе с плавающей запятой:
f"{0.1:.28f}" # '0.1000000000000000055511151231' f"{0.2:.28f}" # '0.2000000000000000111022302463'
Однако, в отличие от sum()
, fsum()
поможет вам уменьшить неточность, когда вы складываете очень большие и очень маленькие числа вместе:
from math import fsum sum([1e-16, 1, 1e16]) # 1e+16 fsum([1e-16, 1, 1e16]) # 1.0000000000000002e+16 sum([1, 1, 1e100, -1e100] * 10_000) # 0.0 fsum([1, 1, 1e100, -1e100] * 10_000) # 20000.0
Ух ты! Второй пример довольно неожиданный и полностью дискредитирует sum()
. С помощью sum()
в результате вы получите 0,0
. Это довольно далеко от правильного результата 20000.0
, который вы получите с помощью fsum()
.
Объединение объектов с помощью itertools.chain()
Если вы ищете удобный инструмент для объединения или связывания итерируемых объектов, рассмотрите возможность использования chain()
из itertools
. Эта функция может принимать несколько объектов и строить итератор, который выдает элементы из первого, из второго и так далее, пока не исчерпает все входные итерации:
from itertools import chain numbers = chain([1, 2, 3], [4, 5, 6], [7, 8, 9]) numbers # <itertools.chain object at 0x7f0d0f160a30> next(numbers) # 1 next(numbers) # 2 list(chain([1, 2, 3], [4, 5, 6], [7, 8, 9])) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
В данном примере вы получаете доступ к последовательным элементам из чисел с помощью next()
. Если вместо этого вы хотите работать со списком, вы можете применить list()
для использования итератора и возврата обычного списка Python.
chain()
также является хорошим вариантом для объединения списков в Python:
from itertools import chain matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] list(chain(*matrix)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Чтобы объединить списки с помощью chain()
, вам нужно использовать итеративный оператор распаковки *
. Этот оператор распаковывает все входные итерации, так что chain()
может работать с ними и генерировать соответствующий итератор. Последний шаг – вызвать list()
для создания желаемого плоского списка.
Объединение строк с помощью str.join()
Как мы уже видели, функция sum() не объединяет строки. Если вам нужно это сделать, то предпочтительным и самым быстрым инструментом, доступным в Python, является str.join()
. Этот метод принимает последовательность строк в качестве аргумента и возвращает новую объединенную строку:
greeting = ["Hello,", "welcome to", "Pythonist!"] " ".join(greeting) # 'Hello, welcome to Pythonist!'
Обратите внимание, что .join()
использует строку, для которой вы вызываете метод, в качестве разделителя во время конкатенации. В этом примере вы вызываете .join()
для строки, состоящей из одного символа пробела " "
, поэтому исходные строки разделяются пробелами.
Заключение
Итак, сегодня мы разобрали, что такое функция sum() в Python. Теперь вы можете использовать её для сложения числовых значений. Эта функция обеспечивает эффективный, читаемый и питонический способ решения задач сложения в коде. Также мы поговорили про альтернативы функции sum()
и в каких случаях их лучше использовать.
Успехов в написании кода!
Перевод статьи «Python’s sum(): The Pythonic Way to Sum Values».