Subtraction of within a list [duplicate] - python

This question already has answers here:
Compare two adjacent elements in same list
(2 answers)
Multiply Adjacent Elements
(5 answers)
Rolling or sliding window iterator?
(29 answers)
Closed 1 year ago.
i'm using Python and I have the following list A = [10,20,30,40]
how can obtain a new list such as I'm adding the second element to the first, the third to the second and fourth to the third. Meaning the output would be [30,50,70].

Can use simple list comprehension like this:
a = [10,20,30,40]
b = [a[i] + a[i+1] for i in range(len(a)-1)]
b
[30, 50, 70]

Take a look at the pairwise recipe from the itertools module (which will be added as a function of itertools in 3.10). Once you've copied that, you can just do:
[x + y for x, y in pairwise(A)]
or for fun with less custom code, add imports from operator import add and from itertools import starmap and you can make an iterator that produces the results lazily with:
starmap(add, pairwise(A)) # Wrap in list if you need a list

a = [10,20,30,40,50]
new_list = []
for i in range(1, len(a)):
new_list.append(a[i] + a[i-1])
When we do range(1, len(a)), we create a set of indexes which are [1,2,3,4].
So when we do:
for i in range(1, len(a)): it's kind of like doing for i in range [1,2,3,4].
If we now imagine we are doing:
for i in [1,2,3,4]:
new_list.append(a[i] + a[i-1])
What it's doing is getting the current value of a at i and adding it a at the previous index i-1 and appending the result to a new list.

Related

Dynamic get nested list according to index [duplicate]

This question already has answers here:
Indexing nested list by a list
(4 answers)
Closed 1 year ago.
Let's say we have 2 lists, one is nested lists, like:
a = [[[['test'],['test1']], ['test2']], ['test3', 'test4']]
the other one stores index:
b = [0,1,0]
so we can retrive test2 with:
a[0][1][0]
I am wondering is there any convenient way to retrive value from nested list according to index list?
How about something like this:
a = [[[["test"], ["test1"]], ["test2"]], ["test3", "test4"]]
b = [0, 1, 0]
item = a
for i in b:
item = item[i]
print(item) # test2
This sounds like a perfect use case for some functional programming and the reduce method:
from functools import reduce
a = [[[['test'],['test1']], ['test2']], ['test3', 'test4']]
b = [0,1,0]
print(reduce(lambda array, index : array[index], b, a))
# Make it into a re-useable function:
follow_array = lambda nested, indices : reduce(lambda array, index : array[index], indices, nested)
print(follow_array(a, b))
The nested list is used as the initializer for the reduce function which then reduces over the array of indices finding going level by level till it finds the result. The inner lambda function used by reduce takes the next indice and pulls out the array at that nesting level when is used as input for the next iteration of reduce.

what comes before "for i in range (...)" [duplicate]

This question already has answers here:
Understanding slicing
(38 answers)
Closed 2 years ago.
I have a simple question, looking at the following code:
letters = [hand[i]][:1] for i in range(5)]
What does the argument before 'for I in range(5)' do?? I can't seem to figure it out.
A simple list comprehension has three parts:
my_list = [A for B in C]
This translates exactly into:
my_list = []
for B in C:
my_list.append(A)
So the part before for determines what goes into the list you're creating.
In your case, you could also write it like this:
letters = []
for i in range(i):
letters.append(hand[i][:1]])
The upper piece of code is called list comprehension:
https://docs.python.org/3/tutorial/datastructures.html
So the upper code could be explicitly written out as:
hand # some data. From your code it should be a nested list, eq: hand = [ [...],[...],... ]
letters = []
for i in range(5): # iterates trough 0-4
element = hand[i][:1]
letters.append(element)
So this is just a very short way of constructing a list. You read it out lout like so:
For every i from range(5) take element(s) hand[i][:1] and assign it to a new list letters.
If your question is about the part hand[i][:1], then this is a slice from a nested list. For example:
hand = [
[0,1,2,3],
[4,5,6,7],
...
]
hand[0] == [0,1,2,3]
hand[0][:1] == [0]
hand[1][:1] == [4] # mind it is a slice, so you are left with a list!!

Exclude an element in a list [duplicate]

This question already has answers here:
Slicing out a specific from a list
(2 answers)
Index all *except* one item in python
(11 answers)
Closed 2 years ago.
Is it possible to use slice but on a specific element on a list? For example a = [1,2,3,4,5,6,7,8,9] I want to make a for loop that prints out the whole list except the second element.
I want to make something like this:
for i in a[something_slice]:
print(i)
Is this possible?
For excluding just one element, the 2 slice lst[:i] + lst[i + 1:] approach proposed by #Applet123 is probably the fastest (Or perhaps a excluded = lst.pop(1) to extract the excluded element and for x in lst: print(x) for printing all the others; then lst.insert(1,excluded) to put the excluded element back on the list. See data structures docs for details).
If you just want to filter out certain indexes, instead of a for loop I recommend you use a more pythonic (and intuitive) approach based on list comprehensions and enumerate:
myList = [1,2,3,4,5,6,7,8,9]
excludedIndices = [1]
myFilteredList = [x for i, x in enumerate(myList) if i not in excludedIndices]
print (myFilteredList)
# output:
# [1,3,4,5,6,7,8,9]
# or, to actually print each element individually:
for x in myFilteredList:
print (x)
# which can also work as a 2-liner with inline filtering:
for i, x in enumerate(myList):
if i not in excludedIndices: print(x)
Also check out python usage of filter and map builtin functions, which may be overkill for this purpose but still offer a general and more powerful solution for this kind of processing:
# filters an enumerated element
def myFilter(element):
return element[0] not in excludedIndices
# maps an enumerated element to a function
def myMap(element):
print(element[1])
# runs myMap function for each enumerated element on the list filtered by myFilter
for x in map(myMap,filter(myFilter,enumerate(myList))): pass
Which you can also turn into a one-liner using lambda expressions:
for x in map(lambda x: print(x[1]),filter(lambda x: x[0] not in excludedIndices,enumerate(myList))): pass
you can do it without slicing, using enumerate()
index_to_skip=1
for idx,item in enumerate(a):
if idx!=index_to_skip:
print(item)
If you actually want to slice the list, you can use 2 slices to slice around it:
def exclude(lst, i):
return lst[:i] + lst[i + 1:]
exclude([1, 2, 3, 4, 5], 1) # [1, 3, 4, 5]
If you just want to loop through it, you could alternatively just skip when the index reaches the value you want to skip:
for i, v in enumerate(a):
if i == 1:
continue
print(v)

Setting a range as an argument in itertools.permutations [duplicate]

This question already has answers here:
Powersets in Python using itertools
(3 answers)
Closed 3 years ago.
I want to print all permutations of length 1-4 for the following list [1,2,3,4]
I know I could just set up a for-loop and pass in the for-loop index as an argument, but I was trying to get the following code to work:
import itertools
nums = [1,2,3,4]
perms = itertools.permutations(nums,range(1,4))
print(list(perms))
The hope was that the argument range(1,4) would run the intertools.permutations(nums) on string lengths 1, 2, 3 and 4.
Any ideas if it is possible to do this using the itertools notation?
Would it also be possible to print the case for length = 1 as:
(1), (2), (3), (4)
not
(1,), (2,), (3,), (4,)
Chain together 4 calls of permutations:
from itertools import chain, permutations
nums = [1,2,3,4]
perms = list(chain.from_iterable(permutations(nums, i) for i in range(1,5)))
print(perms)
If you want to print the 1-tuples as individual values, you'll need to handle that separately:
for t in perms:
if len(t) == 1:
print("(t[0])")
else:
print(t)
That's if you are concerned about the appearance of the tuple. If you truly want a non-tuple value, you'll need to extract the value separately, and keep in mind that 1 and (1) are the exact same value.
perms = list(nums, # permutations(nums, 1) == nums
chain.from_iterable(permutations(nums, i) for i in range(2,5)))
You can also write it as a generator expression:
perms = (it for i in range(1, 4) for it in itertools.permutations(nums,i))

Create sub-lists in lists in Python [duplicate]

This question already has answers here:
Nested List Indices [duplicate]
(2 answers)
Having trouble making a list of lists of a designated size [duplicate]
(1 answer)
Closed 9 years ago.
I'm trying to figure out how to add a sub-list to a list in Python. For example, the code I was using before was just:
pop = [[],[],[],[],[],[],[],[],[],[]]
But I want to add user input to the length of the pop array, ie. how many arrays are added. I've looked at some other stackoverflow questions, and some of them suggested something like:
popLen = 5
pop = [None]*popLen
But when I try that it creates a list with 5 None elements instead of an empty array. I've tried:
pop = [[]]*popLen
What's the proper way to sub-lists?
pop = [[]]*popLen should work, but it is likely not what you want since it creates a list filled with the same nested list popLen times, meaning that a change to one of the list elements would appear in the others:
>>> a = [[]] * 3
>>> a[0].append(42)
>>> a
[[42], [42], [42]]
A better alternative would be
pop = [[] for _ in range(popLen)] # use xrange() in Python 2.x
which eliminates this issue:
>>> a = [[] for _ in range(3)]
>>> a[0].append(42)
>>> a
[[42], [], []]
You can do:
pop = [[] for x in range(popLen)]
Don't try to multiply [[]] - that will actually work, but will do something different than you expect (it will give you copies of the same list, so you cannot change them independently).

Categories