This question already has answers here:
Python: Finding differences between elements of a list
(12 answers)
Closed 3 months ago.
list = [4, 7, 11, 15]
I'm trying to create a function to loop through list items, and find the difference between list[1] and list[0], and then list[2] and list[1], and then list[3] and list[2]... and so on for the entirety of the list. I am thinking of using a for loop but there might be a better way. Thanks.
output would be:
list_diff = [3, 4, 4]
def difference(list):
for items in list():
or
def difference(list):
list_diff.append(list[1] - list[0])
list_diff.append(list[2] - list[1])
etc.
...
If you are in Python 3.10+ you could try pairwise:
And you should try NOT to use the built-in list as the variable name.
It's quite easy and straightforward to make this one-line into a function.
from itertools import pairwise
>>>[b-a for a, b in pairwise(lst)] # List Comprehension
[3, 4, 4]
# Or just zip()
diffs = [b-a for a, b in zip(lst, lst[1:]) ] # no import
You can simply loop for each item starting from element 1:
def diff(source):
return [source[i] - source[i - 1] for i in range(1, len(source))]
print(diff([4, 7, 11, 15])) # [3, 4, 4]
num_list = [4, 7, 11, 15]
def difference(numbers):
diff_list = []
for i in range(1, len(numbers)):
diff_list.append(numbers[i] - numbers[i - 1])
return diff_list
print(difference(num_list)) # [3, 4, 4]
Related
I want to write a code that contains a sublist , that only stops once the element of the list is a certain number , for example 9.
I´ve already tried using different operators , if statements .
def sublist (list):
return [x for x in list if x <9]
[7,8,3,2,4,9,51]
the output for the list above should be :
[7,8,3,2,4]
List comprehensions really are for making mapping/filtering combinations. If the length depends on some previous state in the iteration, you're better off with a for-loop, it will be more readable. However, this is a use-case for itertools.takewhile. Here is a functional approach to this task, just for fun, some may even consider it readable:
>>> from itertools import takewhile
>>> from functools import partial
>>> import operator as op
>>> list(takewhile(partial(op.ne, 9), [7,8,3,2,4,9,51]))
[7, 8, 3, 2, 4]
You can use iter() builtin with sentinel value (official doc)
l = [7,8,3,2,4,9,51]
sublist = [*iter(lambda i=iter(l): next(i), 9)]
print(sublist)
Prints:
[7, 8, 3, 2, 4]
To begin with, it's not a good idea to use python keywords like list as variable.
The list comprehension [x for x in list if x < 9] filters out elements less than 9, but it won't stop when it encounters a 9, instead it will go over the entire list
Example:
li = [7,8,3,2,4,9,51,8,7]
print([x for x in li if x < 9])
The output is
[7, 8, 3, 2, 4, 8, 7]
To achieve what you are looking for, you want a for loop which breaks when it encounters a given element (9 in your case)
li = [7,8,3,2,4,9,51]
res = []
item = 9
#Iterate over the list
for x in li:
#If item is encountered, break the loop
if x == item:
break
#Append item to list
res.append(x)
print(res)
The output is
[7, 8, 3, 2, 4]
This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 4 years ago.
The given code flattens the vector but I'd like to understand the execution order of the two for loops. I've checked the Python Docs too but the execution pattern is not given.
>>> # flatten a list using a list comprehension with two 'for'
>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [num for elem in vec for num in elem]
[1,2,3,4,5,6,7,8,9]
As I understand, execution order is like abstraction (left to right)? Is there any other opinion about it.
This link is flatten using lambda expression, and my question is regarding validation of two for loop execution in List Comp: How to make a flat list out of list of lists?
It works left to right and is the short form of:
vec = [[1,2,3], [4,5,6], [7,8,9]]
flatten = []
for elem in vec:
for num in elem:
flatten.append(num)
This will give you the same output as [num for elem in vec for num in elem].
[1, 2, 3, 4, 5, 6, 7, 8, 9]
You are right about it being left to right. It's true when you look at the equivalent too (because of indentation):
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
output = []
for elem in vec: # first layer
for num in elem: # second layer
output.append(num)
This question already has answers here:
Sum a list of lists to get a sum list Python
(2 answers)
Closed 5 years ago.
First off, I am really new to python, and programming in general, and I'm struggling to grasp the concept of nested for loops and nested lists.
In my code below I am trying to take each list inside the list list1 and sum them using a for loop. I am aware that the range function would help somehow.
Code:
def sum_list(list1):
list_of_sums = []
total = 0
for l in list1:
for value in l:
total = total + value
list_of_sums.append(total)
return list_of_sums
Input test:
list1 = [[4, 7, 9], [4, 5, 2], [4, 5, 6]]
print(sum_list(list1))
Output:
[4, 11, 20]
Desired output:
[20, 11, 15]
You have some logical issues in your code. Think carefully when you should reset total and when to append result to the list_of_sums.
def sum_list(list):
list_of_sums = []
for sublist in list:
total = 0
for value in sublist:
total += value
list_of_sums.append(total)
return list_of_sums
you can achieve this by using list comprehension, it's one of the best thing provided by python. it really shirnks you code and yet easy to understand.
following post my help. You can google more on list comprehension, if you like
http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
def sum_list(list1):
return [sum(inner_list) for inner_list in list1]
print sum_list([[4, 7, 9], [4, 5, 2], [4, 5, 6]])
I hope to write the join_lists function to take an arbitrary number of lists and concatenate them. For example, if the inputs are
m = [1, 2, 3]
n = [4, 5, 6]
o = [7, 8, 9]
then we I call print join_lists(m, n, o), it will return [1, 2, 3, 4, 5, 6, 7, 8, 9]. I realize I should use *args as the argument in join_lists, but not sure how to concatenate an arbitrary number of lists. Thanks.
Although you can use something which invokes __add__ sequentially, that is very much the wrong thing (for starters you end up creating as many new lists as there are lists in your input, which ends up having quadratic complexity).
The standard tool is itertools.chain:
def concatenate(*lists):
return itertools.chain(*lists)
or
def concatenate(*lists):
return itertools.chain.from_iterable(lists)
This will return a generator which yields each element of the lists in sequence. If you need it as a list, use list: list(itertools.chain.from_iterable(lists))
If you insist on doing this "by hand", then use extend:
def concatenate(*lists):
newlist = []
for l in lists: newlist.extend(l)
return newlist
Actually, don't use extend like that - it's still inefficient, because it has to keep extending the original list. The "right" way (it's still really the wrong way):
def concatenate(*lists):
lengths = map(len,lists)
newlen = sum(lengths)
newlist = [None]*newlen
start = 0
end = 0
for l,n in zip(lists,lengths):
end+=n
newlist[start:end] = list
start+=n
return newlist
http://ideone.com/Mi3UyL
You'll note that this still ends up doing as many copy operations as there are total slots in the lists. So, this isn't any better than using list(chain.from_iterable(lists)), and is probably worse, because list can make use of optimisations at the C level.
Finally, here's a version using extend (suboptimal) in one line, using reduce:
concatenate = lambda *lists: reduce((lambda a,b: a.extend(b) or a),lists,[])
One way would be this (using reduce) because I currently feel functional:
import operator
from functools import reduce
def concatenate(*lists):
return reduce(operator.add, lists)
However, a better functional method is given in Marcin's answer:
from itertools import chain
def concatenate(*lists):
return chain(*lists)
although you might as well use itertools.chain(*iterable_of_lists) directly.
A procedural way:
def concatenate(*lists):
new_list = []
for i in lists:
new_list.extend(i)
return new_list
A golfed version: j=lambda*x:sum(x,[]) (do not actually use this).
You can use sum() with an empty list as the start argument:
def join_lists(*lists):
return sum(lists, [])
For example:
>>> join_lists([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]
Another way:
>>> m = [1, 2, 3]
>>> n = [4, 5, 6]
>>> o = [7, 8, 9]
>>> p = []
>>> for (i, j, k) in (m, n, o):
... p.append(i)
... p.append(j)
... p.append(k)
...
>>> p
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
This seems to work just fine:
def join_lists(*args):
output = []
for lst in args:
output += lst
return output
It returns a new list with all the items of the previous lists. Is using + not appropriate for this kind of list processing?
Or you could be logical instead, making a variable (here 'z') equal to the first list passed to the 'join_lists' function
then assigning the items in the list (not the list itself) to a new list to which you'll then be able add the elements of the other lists:
m = [1, 2, 3]
n = [4, 5, 6]
o = [7, 8, 9]
def join_lists(*x):
z = [x[0]]
for i in range(len(z)):
new_list = z[i]
for item in x:
if item != z:
new_list += (item)
return new_list
then
print (join_lists(m, n ,o)
would output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Flatten (an irregular) list of lists in Python
for instance, from:
[[1,2,3],'a',[[4],[5,6],7]]
we want to flatten/penetrate the structure and get all the elements at bottom listed in a line:
[1,2,3,'a',4,5,6,7]
# a recursive function to flatten arbitrary nested lists into one simple 1D list
def flatten(inlist,outlist):
for e in inlist:
if isinstance(e,list) :
flatten(e,outlist)
else:
outlist.append(e)
it's a practice of recursive function, :). the "outlist" here serves as a reference for return-list.
there must be better structures...
;)
for example:
For your benefit, here is an implementation that modifies the list in-place:
def flatten_in_place(seq):
if isinstance(seq, list):
for index, item in reversed(list(enumerate(seq))):
if isinstance(item, list):
seq[index: index + 1] = fil(item)
return seq
else:
return [seq]
Usage:
>>> l = [[1, 2], [3, 4], 5, 6, [7, [8, 9]]]
>>> flatten_in_place(l)
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Interestingly enough, the timeit results (t = 1,000,000) show this to be slightly faster than your implementation:
flatten_in_place time: 4.88
flatten time: 5.16
I'm not sure why that is exactly. Any ideas?