For loops with lists? - python-2.7

I'm starting to code in python and I came across this code snippet:
for [x, y] in L:
for ix in range(-1, 2):
for iy in range(-1, 2):
cir = pylab.Circle((x + ix, y + iy), radius=sigma, fc='r')
pylab.gca().add_patch(cir)
at the line 1 I can not understand what is happening because I had never seen anything like it in another programming language. How this works?
for [x, y] in L:
[x, y] is a list? i dont know.

L must be a sequence of lists (or tuples) with two elements, which can be iterated over. So whenever for [x,y] in L: is executed, it picks each item in th sequence one by one and enters into the loop.
let the sequence be L = [[2,3], [4,5], ['Jeff', 7]]
Now here what will happen when for [x,y] in L: will be executed is :- first list in the sequence [2,3] will be picked up and assigned as x and y respectively. And in the next iteration x and y will get the value 4 & 5 respectively. Like wise in third iteration x will be Jeff and y will be 7.
L = [[2,3], [4,5], ['Jeff', 7]]
count = 0
for [x,y] in L:
count += 1
print " Iteration :- %d, \t x :- %s, \t y:- %s" %(count, str(x), str(y))

Yes, [x, y] is a list with two elements. For your loop to work, L must be a list (or other iterable data structure) that contains a bunch of lists with two elements. Each time through the loop one of those lists is copied into [x, y], then the individual values of x and y are used in the body of the loop.
Try this and see if it makes sense:
L = [ [1, 2], [3, 4] ]
for [x, y] in L:
print x
print y

Related

Haskell -- Fill the List With Empty Spaces

I'm implementing a function that takes a [[Int]], and return a [String], it needs to fill the empty place in each sublist with _s, which index is the complement of the input list, and generate a string from the list, the length of each string is the same and is the (maximum of the input number + 1).
For example, if the input is [[1, 2] [0, 1, 2, 3] [1, 3] [0, 2, 3]], the output would be ["_12_", "0123", "_1_3", "0_23"]
I tried my best to do this, and don't know how to insert empty space into the missing part.
getString :: [[Int]] -> [String]
getString x = concat. show. x insert _
where insert _ [] ys = ys
Breaking this down, it seems you need to find the minimum and maximum numbers present.
inputs = [[1, 2], [0, 1, 2, 3], [1, 3], [0, 2, 3]]
listMin = foldl1 min
listMax = foldl1 max
minInput = listMin $ map listMin inputs
maxInput = listMax $ map listMax inputs
We can now readily generate a list from the minimum to the maximum.
ghci> [minInput .. maxInput]
[0,1,2,3]
So now we can map over our inputs with a list comprehension:
[... | x <- inputs]
And let's return a list of all of the digits each time, and use Data.Char.intToDigit to make them characters.
ghci> [[intToDigit y | y <- [minInput..maxInput]] | x <- inputs]
["0123","0123","0123","0123"]
This looks closer, but we actually want '_' if y is not in x. Easy enough with elem.
ghci> :{
ghci| [[if y `elem` x then intToDigit y else '_'
ghci| | y <- [minInput..maxInput]]
ghci| | x <- inputs]
ghci| :}
["_12_","0123","_1_3","0_23"]
I would advise to start with a simpler problem: doing this for a sublist, so map [1,2] to "_12" and [1,3] to "_1_3". Later you can then do padding at the right of underscores to draw a rectangular matrix. You can do this with recursion where you use an accumulator that will each time check if the head of the list is less than, greater than or equal to the accumulator, so:
getRow :: [Int] -> String
getRow = go 0
where go _ [] = …
go i (x:xs)
| … = …
| otherwise = …
Here go is thus a helper function. It starts with go 0 [1,2]. We see that 0 is less than 1, so we yield an underscore and advance to go 1 [1,2], since now i is the same as the head of the list, we emit the number as character, etc. I leave implementing the … parts as an exercise.

Prolog on finding last element of a list with append

So i found a way of solving it from stackoverflow and it involves this answer:
last(X,Y) :-
append(_,[X],Y).
But i can't actually understand how this actually works.
If anyone can help me it would be really helpful.Thanks.
You can use append/3 [swi-doc] in several directions. You can for example pass a list, and look how two lists can append to that list. For example:
?- append(X, Y, [1,4,2,5]).
X = [],
Y = [1, 4, 2, 5] ;
X = [1],
Y = [4, 2, 5] ;
X = [1, 4],
Y = [2, 5] ;
X = [1, 4, 2],
Y = [5] ;
X = [1, 4, 2, 5],
Y = [] ;
false.
As you can see, there are five ways to construct that. For example with X = [] and Y = [1,4,2,5], or with X = [1] and Y = [4,2,5].
We thus define the predicate last/2 as:
last(X, L) :-
append(_, [X], L).
Notice the [X] as second parameter. We here thus specify that the second list should be a singleton list (a list with exactly one element). An empty list, or a list with two or more elements will not unify with [X].
The append/3 predicate will this aim to unify the second list with candidates like we have seen in the example. But only if the second list is an singleton list, it will match, in which case X is unified with the last element.
See the definition on the SWI-Prolog website.
One of the examples is:
?- append(X, [Last], [a,b,c]).
X = [a,b],
Last = c.
It means the Last is the single element in a list.
Think of the imperative way that X appends the "Last" to the end of the list. Then, it becomes the list [a,b,c].
Therefore, to define the last, we could:
mylast(Xs,Last):-
append(_,[Last],Xs). % doesn't care about the rest of the elements except the [Last]

Prolog Choose 3 From List

I have create a prolog program which given a Number a List and Sublist will generate sublists containing N items in each. I am told this can be done with 1 fact and 2 rules. I am given the hint that I chose the first item or I dont which is confusing me. I have the base case and the first case but I hope someone can help me understand the second case.
choose(1, [H], [H]).
choose(N, [H,TL], [H|ST]) :- choose(Less1, TL, ST), Less1 is N-1.
So my third rule I want to choose the second item in the list
choose(N, [F,S|T], [S|ST]) :- choose(Less1, T, ST), Less1 is N-1.
My last rule however is unbalanced and the whole does not work. Any ideas are greatly appreciated!
While this previous answer by #madanasta should already point you in the right direction, we extend on it in this answer by using clpfd:
:- use_module(library(clpfd)).
We define n_from_chosen/3 like this:
n_from_chosen(0,_,[]).
n_from_chosen(N,[X|Es],[X|Xs]) :-
N #> 0,
N #= N0+1,
n_from_chosen(N0,Es,Xs).
n_from_chosen(N,[_|Es],Xs) :-
N #> 0,
n_from_chosen(N,Es,Xs).
Sample query:
?- n_from_chosen(2,[1,2,3,4],Xs).
Xs = [1,2]
; Xs = [1,3]
; Xs = [1,4]
; Xs = [2,3]
; Xs = [2,4]
; Xs = [3,4]
; false.
How about this more general query?
?- n_from_chosen(N,[1,2,3],Xs).
N = 0, Xs = []
; N = 1, Xs = [1]
; N = 2, Xs = [1,2]
; N = 3, Xs = [1,2,3]
; N = 2, Xs = [1, 3]
; N = 1, Xs = [2 ]
; N = 2, Xs = [2,3]
; N = 1, Xs = [3]
; false.
The idea behind the first two clauses is correct in principle. However:
The first clause is of no use when a sublist of length 1 must be found but the original list is not of length 1. This is problematic.
In the second clause, I assume you mean [H|TL].
Given these, a solution to your problem might be:
choose(1, [H|_], [H]).
choose(N, [H|TL], [H|ST]) :- Less1 is N - 1, choose(Less1, TL, ST).
choose(N, [_|T], L) :- choose(N, T, L).
An attempt to explain:
The first clause will generate a sublist of length 1 given any list with at least one element: It will simply unify the third argument with a single-element list containing only the head of the original list.
The second clause will handle cases when sublists of a length greater than 1 are requested, in which case it will unify the third argument with a list containing the head of the original list and a tail which, thanks to recursion, will be a sublist of the original list's tail of a length equal to the requested length minus 1.
The third clause will simply skip over the original list's head and will unify the third argument with a list which, thanks to recursion, will be a sublist of the original list's tail of the requested length.
Thanks to the third clause, Prolog will be able to provide alternative solutions for requested lengths either equal to or greater than 1.
Some results:
?- choose(2, [1,2,3,4], L).
L = [1, 2] ;
L = [1, 3] ;
L = [1, 4] ;
L = [2, 3] ;
L = [2, 4] ;
L = [3, 4] ;
false.
Note that you cannot use this to solve queries with an unbound length variable as you could using #repeat's solution. To achieve that in pure Prolog you would have to change the logic behind the second clause a bit:
choose(N, [H|TL], [H|ST]) :- choose(Less1, TL, ST), N is Less1 + 1.
This might also help clarify how recursion works in this case.
Hope this helps.
(Disclaimer: I am fairly certain that one can provide a far better explanation of how the above solution works (not to mention a better solution).)

Haskell list comprehension compilation error

I want to create a function that given two lists (of floats, but could be anything) gives a list with all the combinations of taking two elements from the first list and putting it in the last and all the combinations of the former putting one of the elements from the last (now with more elements) and putting it back on the first.
For every movement it also gives the greatest value that moved (in the second movement only one moves, that is the value). It should all end when the first list is empty (there would be no second movement).
I can't expect anyone to understand that so, examples:
next [1,2,3,4] [] -> [(([1,2], [3,4], 4), ([1,2,3],[4],3)), (([1,2], [3,4], 4), ([1,2,4],[3],4)), (([1,3], [2,4], 4), ([1,2,3],[4],2)), (([1,3], [2,4], 4), ([1,3,4],[2],4)).....
next [1,2] [3,4] -> [(([], [1,2,3,4],2),)], ())
What I have so far:
module Test where
next :: [Float] -> [Float] -> [(([Float],[Float], Float),([Float],[Float], Float))]
next [] _ = []
next (a:b:[]) s
|a>b = [([],a:b:s, a)]
|otherwise = [([],a:b:s, b)]
next d s = [([x,z], i:j:s, j), b | i <- d, j <- d, i < j, x <- d, z <- d, x < z, z /= i, z /= j, x /= z, x /= i, x /= j, b <- (back [x,z] i:j:s)]
where
back d s = [(i:d, [x,z], i) | i <- s, x <- s, z <- s, x < z, z /= i, x /= z]
Compiling that code gives back an error on the first comprehension list at the | character. I'd kind of understand an error in the back function. Why won't that compile?
The comprehension syntax is
[ <expression> | ... ]
For <expression> you have ([x,z], i:j:s, j), b which is syntactically wrong. Did you mean ([x,z], i:j:s, b)?

List Comprehension: ignore element if it is a substring of another element in the same list

I have the following list
lst = ['abc-123', 'bc', 'bcd-234', 'def-543', 'ijk-092', 'd']
using a combination of list comprehension and filters I can end up with this result
lst = ['abc-123', 'bcd-234', 'def-543', 'ijk-092']
the code I use
lst = [x for x in lst if len(filter(lambda elem: x in elem, lst)) == 1]
how would i do it purely as a list comphrehension, I have tried
lst = [y for x in lst for y in lst if y in x and x != y]
but this returns the substrings instead
['bc', 'bc', 'd', 'd']
Since every element depends on previous elements admitted, to use "pure" list comprehension, you have to take slices of the original list for every element tested during construction of the new list.
To illustrate this, this code works:
L=[]
for l in lst:
a=[l in x for x in L]
if True in a: continue
L.append(l)
Converting this loop to "pure" list comprehension,
L=[]
L=[l for l in lst if True not in [l in x for x in L]]
requires that the latter L refer to the updated L within the current outer loop, which is not the case.
To make this work, the latter L must be replaced with a slice of the original list, lst, as
L=[l for i,l in enumerate(lst) if True not in [l in x for x in lst[0:i]]]
where the slice includes the elements eliminated from the final list, L.
The result is
['abc-123', 'bcd-234', 'def-543', 'ijk-092']
as desired.