How to convert a Tuple{Array{Float64,1},Array{Float64,1}} to Array{Tuple{Float64,Float64},1} in julia - tuples

How may I convert a Tuple{Array{Float64,1},Array{Float64,1}} to Array{Tuple{Float64,Float64},1} ?
Code
#Sampling
function sam()
x = range(0, 10.0, length = 9) |> collect
y = range(0, 10.0, length = 9) |> collect
return (x,y)
end
xy = sam()
typeof(xy)
The code above returns this output:
Tuple{Array{Float64,1},Array{Float64,1}}

The easiest thing to do in your situation is to assign the output of your function to two separate variables, like this:
function foo()
x = [1, 2, 3]
y = [4, 5, 6]
return x, y
end
x, y = foo()
See the docs on multiple return values.
Then you can use zip to turn the vectors into an iterator of tuples:
julia> x, y = foo()
([1, 2, 3], [4, 5, 6])
julia> x
3-element Array{Int64,1}:
1
2
3
julia> y
3-element Array{Int64,1}:
4
5
6
julia> z = zip(x, y)
zip([1, 2, 3], [4, 5, 6])
Note that the output of zip is an iterator, rather than an array of tuples. You can either iterate through the elements of the iterator to get the individual tuples,
julia> foreach(println, z)
(1, 4)
(2, 5)
(3, 6)
or you can collect the iterator if you actually need an array of tuples:
julia> collect(z)
3-element Array{Tuple{Int64,Int64},1}:
(1, 4)
(2, 5)
(3, 6)

Related

How determine if a partial list and a larger list with all of the partial lists' elements, are in the same order?

e.g. [a,a,c,e] and [a,b,c,d,e]. This is what I mean by same order. It shouldn't matter if one of the lists is only partial. To be clear, I am uninterested in sorting anything.
Edit: Apparently I should mention that I mean lists with some different values. e.g. [a,a,c,e] and [a,b,c,d,e] are in the same order. Simply getting rid of duplicates and cutting the bigger list won't work.
We can use itertools.groupby to squash identical consecutive items into a single item of that value. We can then zip together the squashed values with the other list to see if they are the same
from itertools import izip, groupby
def squash(iterable):
return (k for k, _ in groupby(iterable))
def same_order(iterable, reference):
return all(x == y for x, y in zip(squash(iterable), reference))
print(same_order((1, 2, 2, 3, 4), (1, 2, 3, 4, 5)))
# True
print(same_order((1, 2, 2, 1, 3, 4), (1, 2, 3, 4, 5)))
# False
You can first take the unique set of b, then truncate to the size of a (or vice versa)
a = [1,2,3,4]
b = [1,1,2,2,3,4,4,5]
a == list(set(b))[:len(a)]
You can achieve this by first getting the unique elements from partial list a (in the order of a), then get those elements from full list b (in the order of b). Then you can compare the two and see if they are identical.
>>> a = [1, 1, 4, 3]
>>> a = sorted(set(a), key=a.index) # Remove duplicate elements, but keep the original order
>>> a
[1, 4, 3]
>>> b = [1, 2, 4, 3, 5]
>>> b = [x for x in sorted(set(b), key=b.index) if x in a] # Get unique elements of a from b in order of b, and filter them out to get only elements present in a
>>> a == b
True
>>> a = [4, 3, 2, 1]
>>> a = sorted(set(a), key=a.index) # Remove duplicate elements, but keep the original order
>>> b = [1, 2, 4, 3, 5]
>>> b = [x for x in sorted(set(b), key=b.index) if x in a] # Get unique elements of a from b in order of b, and filter them out to get only elements present in a
>>> a == b
False

Combine two lists of different length python

I have this code:
L = [1, x, x**2]
L2 = [1, 2*x]
def my_mul(x,y):
if x == None: return y
if y == None: return x
return x*y
map(my_mul, L, L2)
This produces what I want, which is a element-wise product of L and L2.
[1, 2*x^2, x^2]
But is there a more pythonic way of achieving this?
Concretely, can I do this without defining my own function?
The code below should achieve what you need
import itertools
import operator
l1 = [1, 2, 3]
l2 = [1, 2, 3, 4]
list(itertools.starmap(operator.mul, itertools.zip_longest(l1, l2, fillvalue=1)))
# result [1, 3, 9, 4]
Explanation
zip_longest will zip and fill missing values from shorter list:
itertools.zip_longest(l1, l2, fillvalue=1)
[(1, 1), (2, 2), (3, 3), (1, 4)]
starmap will apply multiplication operator to every integer pair

python3.2)append two element in a list(lists in a list)

If I have an input like this (1, 2, 3, 4, 5, 6)
The output has to be ... [[1, 2], [3, 4], [5, 6]].
I know how to deal with if it's one element but not two.
x=[]
for number in numbers:
x.append([number])
I'll appreciate your any help!
Something like this would work:
out = []
lst = (1,2,3,4,5,6,7,8,9,10)
for x in range(len(lst)):
if x % 2 == 0:
out.append([lst[x], lst[x+1]])
else:
continue
To use this, just set lst equal to whatever list of numbers you want. The final product is stored in out.
There is a shorter way of doing what you want:
result = []
L = (1,2,3,4,5,6,7,8,9,10)
result = [[L[i], L[i + 1]] for i in range(0, len(L) - 1, 2)]
print(result)
You can use something like this. This solution also works for list of odd length
def func(lst):
res = []
# Go through every 2nd value | 0, 2, 4, ...
for i in range(0, len(lst), 2):
# Append a slice of the list, + 2 to include the next value
res.append(lst[i : i + 2])
return res
# Output
>>> lst = [1, 2, 3, 4, 5, 6]
>>> func(lst)
[[1, 2], [3, 4], [5, 6]]
>>> lst2 = [1, 2, 3, 4, 5, 6, 7]
>>> func(lst2)
[[1, 2], [3, 4], [5, 6], [7]]
List comprehension solution
def func(lst):
return [lst[i:i+2] for i in range(0, len(lst), 2)]
Slicing is better in this case as you don't have to account for IndexError allowing it to work for odd length as well.
If you want you can also add another parameter to let you specify the desired number of inner elements.
def func(lst, size = 2): # default of 2 it none specified
return [lst[i:i+size] for i in range(0, len(lst), size)]
There's a few hurdles in this problem. You want to iterate through the list without going past the end of the list and you need to deal with the case that list has an odd length. Here's one solution that works:
def foo(lst):
result = [[x,y] for [x,y] in zip(lst[0::2], lst[1::2])]
return result
In case this seems convoluted, let's break the code down.
Index slicing:
lst[0::2] iterates through lst by starting at the 0th element and proceeds in increments of 2. Similarly lst[1::2] iterates through starting at the 1st element (colloquially the second element) and continues in increments of 2.
Example:
>>> lst = (1,2,3,4,5,6,7)
>>> print(lst[0::2])
(1,3,5,7)
>>> print(lst[1::2])
(2,4,6)
zip: zip() takes two lists (or any iterable object for that matter) and returns a list containing tuples. Example:
>>> lst1 = (10,20,30, 40)
>>> lst2 = (15,25,35)
>>> prit(zip(lst1, lst2))
[(10,15), (20,25), (30,35)]
Notice that zip(lst1, lst2) has the nice property that if one of it's arguments is longer than the other, zip() stops zipping whenever the shortest iterable is out of items.
List comprehension: python allows iteration quite generally. Consider the statement:
>>> [[x,y] for [x,y] in zip(lst1,lst2)]
The interior bit "for [x,y] in zip(lst1,lst2)" says "iterate through all pairs of values in zip, and give their values to x and y". In the rest of the statement
"[[x,y] for [x,y] ...]", it says "for each set of values x and y takes on, make a list [x,y] to be stored in a larger list". Once this statement executes, you have a list of lists, where the interior lists are all possible pairs for zip(lst1,lst2)
Very Clear solution:
l = (1, 2, 3, 4, 5, 6)
l = iter(l)
w = []
for i in l:
sub = []
sub.append(i)
sub.append(next(l))
w.append(sub)
print w

Diagonals at different points of a 2D list in Python

I was wondering how to get the list of values of diagonals that do not pass through the center.
Let's say I have a nested List:
L = [[1,2,3],[4,5,6][7,8,9]]
How would I, say, get the diagonal [2,6]?
I'm not quite sure what you want, but this code gives you all the complete diagonals in each direction:
L = [[1,2,3],[4,5,6], [7,8,9]]
# number of rows, number of columns: ie L is m x n
m, n = len(L), len(L[0])
# Retreive the NE-SW (diag1) and NW-SE (diag2) diagonals
diag1 = []
diag2 = []
for p in range(m+n-1):
diag1.append([])
diag2.append([])
q1 = 0
if p >= n:
q1 = p - n + 1
q2 = m
if p < m-1:
q2 = p+1
for q in range(q1, q2):
x, y = p - q, q
diag1[-1].append(L[y][x])
# To get the other diagonal, read each row "backwards"
x = n - x - 1
diag2[-1].append(L[y][x])
print 'diag1:', diag1
print 'diag2:', diag2
That is:
diag1: [[1], [2, 4], [3, 5, 7], [6, 8], [9]]
diag2: [[3], [2, 6], [1, 5, 9], [4, 8], [7]]
How would you go about amending the code to accept non- m x n nested lists with the characteristic: len(L[i]) > len(L[i+1]).
For example, the following nested list:
[[1,2,3,4,5,6,7,8,9,10],
[11,12,13,14,15,16,17],
[18,19,20,21,22],
[23,24,25,26],
[27,28],
[29]]
should produce:
[[1],
[2,11],
[3,12,18],
[4,13,19,23],
[5,14,20,24,27],
[6,15,21,25,28,29],
[7,16,22,26],
[8,17],
[9],
[10]

Prolog - generate correct bracketing

I'd like to get some help in the following exam problem, I have no idea how to do this:
Input: a list of numbers, eg.: [1,2,3,4]
Output: every possible correct bracketing. Eg.: (in case of input [1,2,3,4]):
((1 2) (3 4))
((1 (2 3)) 4)
(1 ((2 3) 4))
(1 (2 (3 4)))
(((1 2) 3) 4)
Bracketing here is like a method with two arguments, for example multiplication - then the output is the possible multiplication orders.
Your assignment could be seen as the inverse of 'computing the yield of a binary tree'.
You can code yield with 2 recursive calls and append/3:
yield((L, R), Y) :-
yield(L, Ly),
yield(R, Ry),
append(Ly, Ry, Y).
yield(T, [T]).
test:
?- yield(((1,2),(3,4)),Y).
Y = [1, 2, 3, 4] ;
Y = [1, 2, (3, 4)] ;
Y = [ (1, 2), 3, 4] ;
Y = [ (1, 2), (3, 4)] ;
Y = [ ((1, 2), 3, 4)].
Thus abstractly, yield/2 should solve your assignment, when called in this way:
?- yield(BinTree, [1,2,3,4]).
but, of course, that do not terminate. Clearly, the SLD resolution (Prolog computing algorithm) can't solve this problem without some help.
But if you recall that append/3 can generate all the alternatives left & right lists that compose the appended:
?- append(L,R,[1,2,3,4]).
L = [],
R = [1, 2, 3, 4] ;
L = [1],
R = [2, 3, 4] ;
L = [1, 2],
R = [3, 4] ;
L = [1, 2, 3],
R = [4] ;
L = [1, 2, 3, 4],
R = [] ;
false.
you can attempt to change the order of calls to get your solution.
Beware that you need sufficiently instantiated arguments before recursing, thus check the 'output' of append. You can test with
...
Yr = [_|_],
...
I also suggest to rename the predicate and change the order of arguments for clarity:
?- brackets([1,2,3,4],B).
B = 1* (2* (3*4)) ;
B = 1* (2*3*4) ;
B = 1*2* (3*4) ;
B = 1* (2*3)*4 ;
B = 1*2*3*4 ;
false.
This code works with SWI-Prolog (nextto/3).
You can explain to Prolog what you want, then ask him all the solutions :
bracket([A,B], [A,B]).
bracket(In, Out) :-
member(X, In),
nextto(X,Y, In),
append_3(A, [X,Y], B, In),
append_3(A, [[X,Y]], B, Temp),
bracket(Temp, Out).
append_3(A,B,C, Out) :-
append(A, B, Temp),
append(Temp, C, Out), !.
all_brackets(R) :-
setof(L, bracket([1,2,3,4], L), R).
you get
?- all_brackets(R), maplist(writeln, R).
[[[1,2],3],4]
[[1,2],[3,4]]
[[1,[2,3]],4]
[1,[[2,3],4]]
[1,[2,[3,4]]]
R = [[[[1,2],3],4],[[1,2],[3,4]],[[1,[2,3]],4],[1,[[2,3],4]],[[1,2],[3,4]],[1,[2,[3,4]]]].