Understanding Python list.append behavior - python-2.7

Why in the following example is appending to the big_l in the for loop changes also the last lists already added to the big_l?
l=[1,2,3,4,5]
big_l=[]
def f(ll):
x=ll.pop(0)
ll.append(x)
return ll
for i in range(4):
big_l.append(l)
print l,big_l
l=f(l)
It prints:
[1, 2, 3, 4, 5] - [[1, 2, 3, 4, 5]]
[2, 3, 4, 5, 1] - [[2, 3, 4, 5, 1], [2, 3, 4, 5, 1]]
[3, 4, 5, 1, 2] - [[3, 4, 5, 1, 2], [3, 4, 5, 1, 2], [3, 4, 5, 1, 2]]
[4, 5, 1, 2, 3] - [[4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3], [4, 5, 1, 2, 3]]

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.

convert data from 2d to 3d numpy array

If I have a 2d array like:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
And I want to end up with a 3d array like:
array([[[0, 4, 8],
[1, 5, 9]],
[[2, 6, 10],
[3, 7, 11]]])
How should I reshape the array to get what I want?
Reshape and permute axes -
In [11]: a # Input array
Out[11]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [12]: a.reshape(-1,2,2).transpose(1,2,0)
Out[12]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])
With np.moveaxis -
np.moveaxis(a.reshape(-1,2,2), 0,-1)
Generalizing it and assuming that you want the length along the first axis as half of no. of columns -
In [16]: m,n = a.shape
In [17]: a.reshape(m,-1,2).transpose(1,2,0)
Out[17]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])
If that length is supposed to be 2 -
In [15]: a.reshape(m,2,-1).transpose(1,2,0)
Out[15]:
array([[[ 0, 4, 8],
[ 1, 5, 9]],
[[ 2, 6, 10],
[ 3, 7, 11]]])

Skipping list of lists elements

I have this nested list:
list = [[1, 2, 3, 4],
[2, 7, 2, 1],
[3, 3, 7, 5],
[4, 4, 1, 7]]
And I'm trying to skip the first list of this nested list, and the first element of each list. I want it to become like this:
list = [[7, 2, 1],
[3, 7, 5],
[4, 1, 7]]
So far I have this:
% skip first list in list of lists
skip_first_list([_|Tail], Tail).
% attemping to skip first element in each of the lists
skip_first_list([[_ | HeadTail] | Tail], X) :-
skip_first_list(Tail, R),
append(R, [HeadTail], X).
Which does not produce the correct result:
?- skip_first_list([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]], X).
X = [[2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]] ;
X = [[3, 3, 7, 5], [4, 4, 1, 7], [2, 3, 4]] ;
X = [[4, 4, 1, 7], [7, 2, 1], [2, 3, 4]] ;
X = [[3, 7, 5], [7, 2, 1], [2, 3, 4]] ;
false.
Whereas I'm after this answer:
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]]
My result so far seems to be showing I'm appending in a reverse/incorrect order, How can I fix this? I don't really understand what order Prolog evaluates expressions. Any any would be appreciated.
Well the specification is that you provide a list of lists and that:
the first sublist is ignored (not part of the output); and
that for the remaining sublists, all heads are ignored as well.
So we better split this into two predicates:
remove_heads/2, which removes the heads of all sublists; and
remove_upper_left/2 which remove the first sublist, and then uses the above predicate to pop the heads of the sublists.
We can perform remove_heads/2 for instance with recursion:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
finally our remove_upper_left/2 simply ignores the head of the list, and makes a call to remove_heads with the tail:
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
Or in full:
remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
remove_heads(T,T2).
remove_upper_left([_|T],T2) :-
remove_heads(T,T2).
This then produces:
?- remove_upper_left([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]],X).
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]].
and works in the opposite direction as well:
?- remove_upper_left(X, [[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]]).
X = [_G1364, [_G1370, 1, 2, 3, 4], [_G1376, 2, 7, 2, 1], [_G1382, 3, 3, 7, 5], [_G1388, 4, 4, 1|...]].
So here it prepends a variable to every list, and prepends a variable (possibly a sublist) to the output.
Furthermore we have here two predicates at the price of one: we can also use remove_heads/2 in the future if we want to pop the heads of all the sublists in a list of lists.

Find largest independent set in list

I have python lists like follows
>>>[[2, 0, 10], [2, 0, 11], [2, 1, 12], [2, 1, 13], [4, 3, 5], [4, 3, 7], [7, 6, 8], [7, 6, 10], [10, 9, 2], [10, 9, 11], [13, 14, 15]]
>>>[[0, 1, 3], [0, 1, 6], [3, 2, 0], [3, 2, 6], [3, 4, 5]]
I want to extract largest list set containing uncommon values. For example, for latter list, the largest independent set should be [[0, 1, 6], [3, 4, 5]], whereas for the former, it should be [[2, 0, 12], [4, 3, 5], [7, 6, 8], [10, 9, 11], [13, 14, 15]]. It may be similar with maximum independent set problem, but I have no idea about this as I know nothing about graphs. So any suggestion to solve this problem? Thanks in advance.

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]]