How to get the following two list? - list

Hello I am working with some lists I have the following list:
a = [1,2,3,4,5,6]
I would like to get the these two lists from a:
b = [2,3,4,5,6]
c = [1,2,3,4,5]
I would like to get the firt one removing the first element of a and the second one removing the last element of a, I tried:
b = a
c = a
b.pop(0)
c.pop(len(a)-1)
print(b)
print(c)
print(a)
However the output is:
[2, 3, 4, 5]
[2, 3, 4, 5]
[2, 3, 4, 5]
that is affecting my fist list, I am not sure about what I am doing, I would like to appreciate support with this.

You should not modify the original list - it's simpler than you think, just slice the input list passing the right indexes. Try this:
a = [1, 2, 3, 4, 5, 6]
b = a[1:]
c = a[:-1]
a
=> [1, 2, 3, 4, 5, 6]
b
=> [2, 3, 4, 5, 6]
c
=> [1, 2, 3, 4, 5]

I think slicing would be ok:
b =a[1:];
c =a[:-1]

Related

Creating [1,2,3...,N] list in Prolog

I'd like to create a predicate arrayLEQ(L,N) that is true when L = [1,2,3,...,N].
I tried to do it recursively:
arrayLEQ(L,N) :- arrayLEQ([],L,1,N).
arrayLEQ(L1,L2,N,N) :- append(L1,[N],L2).
arrayLEQ(L1,L2,F,N) :- Fnext is F+1, append(L1,[F],L1n), arrayLEQ(L1n,L2,Fnext,N).
At first I thought that it will work, but sadly it doesn't.
When I do:
?- arrayLEQ(L,5) I get L = [1,2,3,4,5] which is the right answer, but Prolog is ready to look for another answer, which is not wanted.
Would you mind explaining to me what I did wrong and why Prolog tries to look for another answer to this predicate, even if it doesn't exist.
Let's have a look at tracer after the first query succeed:
?- arrayLEQ(L,5).
L = [1,2,3,4,5].
more
Redo:arrayLEQ([1, 2, 3, 4], _5040, 5, 5)
Call:_5844 is 5+1
Exit:6 is 5+1
Call:lists:append([1, 2, 3, 4], [5], _5854)
Exit:lists:append([1, 2, 3, 4], [5], [1, 2, 3, 4, 5])
Call:...
Call:_5880 is 6+1
Exit:7 is 6+1
Call:lists:append([1, 2, 3, 4, 5], [6], _5890)
Exit:lists:append([1, 2, 3, 4, 5], [6], [1, 2, 3, 4, 5, 6])
Call:arrayLEQ([1, 2, 3, 4, 5, 6], _5040, 7, 5)
Call:_5922 is 7+1
Exit:8 is 7+1
Call:lists:append([1, 2, 3, 4, 5, 6], [7], _5932)
Exit:lists:append([1, 2, 3, 4, 5, 6], [7], [1, 2, 3, 4, 5, 6, 7])
Call:arrayLEQ([1, 2, 3, 4, 5, 6, 7], _5040, 8, 5)
Call:_5970 is 8+1
Exit:9 is 8+1
and so on...
You can see that your program keeps adding element into the list, without stopping. So there are two solutions:
Adding a cut (!): arrayLEQ(L1,L2,N,N):- !, append(L1,[N],L2). It works but maybe (in my opinion) there is a better solution.
When adding an element, you don't check if you have already passed the threshod you set (in this case 5). So you just have to add F < N before doing Fnext is F+1. So: arrayLEQ(L1,L2,F,N) :- F < N, Fnext is F+1, append(L1,[F],L1n), arrayLEQ(L1n,L2,Fnext,N). (personally i prefer this solution)
So the query now (with second solution):
?- arrayLEQ(L,5).
L = [1, 2, 3, 4, 5].
more.
false.
I suggest you to not use append/3 because in this case is not necessary at all and write someting like this:
orderedList(L,N):-
orderedList(L,1,N).
orderedList([N],N,N). %you can add a cut ! here, to avoid further search
orderedList([H|T],C,N):-
C < N,
H is C,
C1 is C+1,
orderedList(T,C1,N).
?- orderedList(L,5).
L = [1, 2, 3, 4, 5]
more
false
Then if you need to return an empty list, wou can add a predicate to handle this case easily... BTW check also the question linked in the comments by #repeat

How do I reassign the first index of this matrix 'a' without changing 'b'?

I am trying to change a[0][0] without changing the matrix b. Is there an easy way to do this? I tried to use b = list(a) and b = a[:] but no luck.
a = [[1,2,3,4],[1,2,3,4]]
b = a
print(a)
print(b)
a[0][0] = "WWWW"
print(a)
print(b)
Output:
[[1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4]]
[['WWWW', 2, 3, 4], [1, 2, 3, 4]]
[['WWWW', 2, 3, 4], [1, 2, 3, 4]]
This worked but it seems like there could be a better way?
a = [[1,2,3,4],[1,2,3,4]]
b = [[0,0,0,0], [0,0,0,0]]
for i in range(len(a)):
for j in range(len(a[i])):
b[i][j] = a[i][j]
print(a)
print(b)
a[0][0] = "WWWW"
print(a)
print(b)
Output:
[[1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4]]
[['WWWW', 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4]]
Lists are mutable.
This link explains in detail what mutable objects are
This doesn't work in your code because, you are using nested lists. If you were to do just a[0]="something", this wouldn't reflect in b however if you do something like this a[0][0]="wow" this would.
b = a[:]
The nested list in both a and b still point towards the same block of memory.
To solve this try:
import copy
a = [[1,2,3,4],[1,2,3,4]]
b = copy.deepcopy(a)
Explained in detail here

Splitting Lists In Python

How can I go about splitting a list into 2 separate lists based on every 5 numbers. This is what im trying to get it to look like.
list = [a,a,a,a,a,b,b,b,b,b,c,c,c,c,c,d,d,d,d,d]
newlista = [a,a,a,a,a,c,c,c,c,c]
newlistb = [b,b,b,b,b,d,d,d,d,d]
Ive been looking at itertools, not sure if im on the right path.
You can do this with list comprehension and slices:
In [1]: a, b, c, d, = 1, 2, 3, 4
In [2]: l = [a,a,a,a,a,b,b,b,b,b,c,c,c,c,c,d,d,d,d,d]
In [3]: [l[i:i+5] for i in range(0,15,10)]
Out[3]: [[1, 1, 1, 1, 1], [3, 3, 3, 3, 3]]
In [4]: [l[i:i+5] for i in range(5,20,10)]
Out[4]: [[2, 2, 2, 2, 2], [4, 4, 4, 4, 4]]

How to copy list items certain amount of times?

I have a big list of around 2000 numbers in the list. This is just an example of what I want.
I have list1=[1,2,3,4] and list2=[1,3,2,5]. I want it so that list1[i] will be used list2[i] times in the new list.
So for this example the new list would be:list3=[1,2,2,2,3,3,4,4,4,4,4]
The new list3 has 1x1, 3x2, 2x3, 5x4.
This isn't pretty and isn't particularly easy to understand, but works:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 2, 5]
>>> import itertools
>>> list3 = list(itertools.chain(*[[list1[i]] * count for i, count in enumerate(list2)]))
>>> list3
[1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4]
Brief explanation...
You can multiply a list:
>>> [1] * 3
[1, 1, 1]
Using this in the list comprehension will get you a list-of-lists:
>>> [[list1[i]] * count for i, count in enumerate(list2)]
[[1], [2, 2, 2], [3, 3], [4, 4, 4, 4, 4]]
You can then use itertools to flatten the list as above.
list1=[1,2,3,4]
list2=[1,3,2,5]
list3 = []
for a, b in zip(list1, list2):
for i in range(b):
list3.append(a)
list3 == [1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4]
Another alternative:
list1=[1,2,3,4]
list2=[1,3,2,5]
z=[]
for x,y in zip(list1,list2):
z.extend([x] * y)
print z

How to select values 2+ after any number in a list?

Is there any way to select the second, third (etc) value from a value in a list in Groovy? I'm still very new to programming in general and am just wondering if there is an easy way to do this.
For example, if I have the list
[1, 2, 3, 4, 5, 6]
I want to select the next two values after each value using a for loop:
for 1: (1, 2, 3)
for 2: (2, 3, 4)
...and so on.
Is that easily possible? Thanks in advance!
If you're using groovy 1.8.1 or later, you can use the take and drop methods:
def foo = [1, 2, 3, 4, 5, 6]
foo.size().times { i ->
println foo.drop(i).take(3)
}
This will result in
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6]
[6]
If you want the iteration to stop at the last group of three, try something like this:
def foo = [1, 2, 3, 4, 5, 6]
if (foo.size() > 2) {
(foo.size() - 2).times { i ->
println foo.drop(i).take(3)
}
}
which gives
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
If you're not using Groovy 1.8.1+, then you can acheive a similar result by writing a function like so:
List split( List foo, int size ) {
(0..foo.size()-size).collect { foo[ it..it+size-1 ] }
}
Then, you can call this like:
split( [1, 2, 3, 4, 5, 6], 3 )
to print
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]