Reverse Part of a List - list

Take list foo
foo = [5, 6, 7, 8, 9, 10, 11, 12]
How can I reverse only the elements of indices x to y within the list?
For example:
x = 1
y = 5
# reverse foo[x:y]
foo = [5, 9, 8, 7, 6, 10, 11, 12]

Python allows you to assign to slices
Slicings may be used as expressions or as targets in assignment or del
statements
thus it's possible to do everything on one line:
foo[x:y] = foo[y-1:x-1:-1]
Note thatfoo[y-1:x-1:-1] has the same meaning as foo[x:y][::-1].

It's as simple as:
foo[x:y] = foo[y - 1:x - 1:-1]
For example:
>>> foo = [5, 6, 7, 8, 9, 10, 11, 12]
>>> foo[1:5] = foo[4:0:-1]
>>> foo
[5, 9, 8, 7, 6, 10, 11, 12]

def reverse(l, x, y):
l[x:y+1] = l[y:x-1:-1]
foo = [5, 6, 7, 8, 9, 10, 11, 12]
x = 1
y = 4
reverse(foo, x, y)
print(foo) # [5, 9, 8, 7, 6, 10, 11, 12]

Related

Prolog: Create a List from a selection of a given List

I want to write a predicate in Prolog, which creates a all possible segments of a given Size of a given List and returns the un-selected elements as a List.
My Code so far:
select_seg(List, Segment, Rest, Size ):-
select_seg(List, Segment, Rest, Size, Size).
select_seg(_,_,_,_, 0):- !.
select_seg(List, [Head_Segs|Tail_Segs],[Head_Rest|Tail_Rest], Size,Acc ):-
select(Head_Segs, List, Head_Rest),
Acc >= 0,
New_Acc is Acc - 1,
select_seg(Head_Rest, Tail_Segs, Tail_Rest, Size, New_Acc).
When I call this predicate with:
select_seg([1,2,3,4,5,6,7,8,9], Seg, R ,3 ).
It returns:
Seg = [1, 2, 3|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 4, 6, 7, 8, 9]|_] ;
This is desired output, except that the list of remaining elements contain three lists for each element in the Segment the List of remaining elements, but should only contain the last one as following:
Seg = [1, 2, 3|_],
R = [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [3, 4, 6, 7, 8, 9]|_] ;
I tried everything, but I am not able to come up with the right solution.
It's combining select with a variant of select:
select_len_seg(Len, L, Seg, Rem) :-
length(Seg, Len),
select_len_seg_(Seg, L, L, Rem).
select_len_seg_([], _, R, R).
select_len_seg_([H|T], F, R, Rem) :-
% Preventing "duplicates" such as [3,2,1]
select_forward(H, F, F0),
select(H, R, R0),
select_len_seg_(T, F0, R0, Rem).
select_forward(E, [H|T], F) :-
select_forward_(T, H, E, F).
select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
select_forward_(T, H, E, F).
Results in swi-prolog:
?- select_len_seg(3, [1,2,3,4,5,6,7,8,9], S, R).
S = [1, 2, 3],
R = [4, 5, 6, 7, 8, 9] ;
S = [1, 2, 4],
R = [3, 5, 6, 7, 8, 9] ;
...
S = [6, 7, 9],
R = [1, 2, 3, 4, 5, 8] ;
S = [6, 8, 9],
R = [1, 2, 3, 4, 5, 7] ;
S = [7, 8, 9],
R = [1, 2, 3, 4, 5, 6] ;
false.

How to square negative numbers in a list in python

How to change this [1, 5, 9, -3, -4, 8, -2] into this [1, 5, 9, 9, 16, 8, 4]
import math
val = [1, 5, -3, 7, -4, -2, 9]
for i in val:
if i < 0:
val[i] = math.sqrt(i)
print(val)
i get ValueError: math domain error if i do the code above
You can simply use a map function to get this done.
import math
val = [1, 5, -3, 7, -4, -2, 9]
val = list(map(lamda x: x * x if x < 0 else x, val))
You can refer below code:
val = [1, 5, -3, 7, -4, -2, 9]
for i in val:
val[i] = i *i
print(val)
Or
import math
val = [1, 5, -3, 7, -4, -2, 9]
for i in val:
if i < 0:
val[i] = math.sqrt(i*-1)
print(val)

Nested lists addition

I have a nested list called a:
a = [[0, 1, 2, 3, 4], [10, 11, 12, 13, 14]]
My desired output is a new list (b) containing the first list in a: [0, 1, 2, 3, 4]. Then I want to append to this list all of the values in [10, 11, 12, 13, 14] added to the last number in [0, 1, 2, 3, 4]:
b = [0, 1, 2, 3, 4, 14, 15, 16, 17, 18]
# Your First List
a =[[0, 1, 2, 3, 4], [10, 11, 12, 13, 14]]
# Your Second List which is initalized as empty.
b = []
# Adding first list from (a) which is a[0] into second list
# a[0] = [0, 1, 2, 3, 4]
# a[1] = [10, 11, 12, 13, 14]
b.extend(a[0])
# b = [0, 1, 2, 3, 4]
# I then want to append to this list all of the values in [10, 11, 12, 13, 14] added
# the last number in [0, 1, 2, 3, 4].
# a[0] = [0, 1, 2, 3, 4]
# a[0][-1] = 4
last_val = a[0][-1]
second_list = a[1] # [10, 11, 12, 13, 14]
for item in second_list:
b.append(item+last_val)
print(b)
# b = [0, 1, 2, 3, 4, 14, 15, 16, 17, 18]

Append to an empty list using a single line for-loop python

I am trying to append numbers from a generator to an empty list using a single line for loop but it returns None. I understand it can be done using a for loop with 2 lines but I was wondering what I am missing. i.e.,
>>> [].append(i) for i in range(10)
[None, None, None, None, None, None, None, None, None, None]
I was hoping to create this in one line:
>>> [].append(i) for i in range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Thank you.
Write a proper comprehension, without append.
>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(i for i in range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Adding Explanation as to what happens,
Append doesn't return anything,
y = []
x = [y.append(i) for i in range(10)]
print(x)
print(y)
produces
[None, None, None, None, None, None, None, None, None, None]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[Program finished]
you can also just cast a range which is a iterable:
list(range(10))
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
also for numpy users:
np.arange(10)
>>> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
or you can use linspace if its more understandable to you (linspace(from,to,pieces)) :
np.linspace(0,9,10)
>>> array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
y = []
[y.append(i) for i in range(10)]
print(y)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

why reversed() list iteration with step doesn't work properly?

def checkio(data):
s1=[]
s2=[]
data.sort()
for x in reversed(data[0:len(data):2]):
s1.append(x)
for y in reversed(data[0:(len(data)-1):2]):
s2.append(y)
print(s1, s2)
checkio([5, 8, 13, 27, 14])
If iteration over data[0:len(data):2] starts at item with the last index, why does the iteration over data[0:(len(data)-1):2] does not start at item with index just before the last?
Reversed takes a list and reverses it.
The slicing notation iterates over the list and returns a new one.
When you call reversed on the slice (with or without stepping) of a list, the slice is created first, and then reversed.
For example, newL = reversed(L[0:len(L):2]) is the same as:
M = L[0:len(L):2]
newL = reversed(M)
Thus, when you say reversed(L[0:len(L)-1:2]), reversed is called on a list containing every other element in L, starting with the first, and excluding the last.
As a side note, L[::2] is the same as L[0:len(L):2], and L[:-1:2] is the same as L[0:len(L)-1:2]. Also, L[::-1] is L in reverse order.
This notation is very powerful.
If you want a checkio([5, 8, 13, 27, 14]) to return [14, 13, 5, 27, 8], then here are a few ways to do it:
>>> L = [5, 8, 13, 27, 14]
>>> L[::-2] + L[-2::-2]
[14, 13, 5, 27, 8]
>>> L = [5, 8, 13, 27, 14]
>>> list(reversed(L))[::2] + list(reversed(L))[1::2]
[14, 13, 5, 27, 8]
>>> L = [5, 8, 13, 27, 14]
>>> list(itertools.chain(itertools.islice(reversed(L), 0, len(L), 2), itertools.islice(reversed(L), 1, len(L), 2)))
[14, 13, 5, 27, 8]
Hope this helps