Check: http://www.scala-lang.org/docu/files/collections-api/collections_40.html
It says ArrayBuffer takes linear time when requesting tail. However, it is much faster when appending
My understanding is that an ArrayBuffer is simply a dynamic array.
How come appending is amortised constant time but getting the last element takes linear time?
tail is not the last element, it is all elements but the first. You want last.
Seq('a', 'b', 'c').head // 'a'
Seq('a', 'b', 'c').tail // Seq('b', 'c')
Seq('a', 'b', 'c').init // Seq('a', 'b')
Seq('a', 'b', 'c').last // 'c'
Related
I have a dictionary of key-value pairs. My value is a nested list. I am trying to make a new nested list out of the old one by combining all the elements with same index together.
I have tried making a new list of the old one,so that it doesn't change my original dictionary. I tired using a loop and indexing my values but it doesn't give me what i need
dict_mutated = []
for key,value,i in dict_ni.items():
dict_mutated['lst_{}'.format(i)] = [item[i] for item in value]
I get an error "ValueError: too many values to unpack (expected 2)"
My input looks like
{lst_0_0 :[['a', 'b', 'c'],['d' ,'e' ,'f'],['g' ,'h' ,'i']],
lst_0_1 :[['a1', 'b1', 'c1'],['d1' ,'e1' ,'f1'],['g1' ,'h1' ,'i1']]}
I expect to get
{lst_0_0: [['a' 'd' 'g'], ['b' 'e' 'h'], ['c' 'f' 'i']],
lst_0_1: [['a1' 'd1' 'g1'], ['b1' 'e1' 'h1'], ['c1' 'f1' 'i1']]
}
Use zip
Ex:
data = {"lst_0_0" :[['a', 'b', 'c'],['d' ,'e' ,'f'],['g' ,'h' ,'i']],
"lst_0_1" :[['a1', 'b1', 'c1'],['d1' ,'e1' ,'f1'],['g1' ,'h1' ,'i1']]}
result = {}
for k, v in data.items():
result[k] = [list(i) for i in zip(*v)]
print(result)
Or a dict comprehension.
result = {k: [list(i) for i in zip(*v)] for k, v in data.items()}
Output:
{'lst_0_0': [['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']],
'lst_0_1': [['a1', 'd1', 'g1'], ['b1', 'e1', 'h1'], ['c1', 'f1', 'i1']]}
I need to generate all possible subset from a character array in MATLAB with reduced execution time.
For example:
input='ABCA';
output ='A',
'B',
'C',
'AB',
'BC',
'CA',
'ABC',
'BCA',
'ABCA'
You can find all these subsets using straight-forward loops. I don't know if it is worth-while vectorizing these, as any vectorization will require large intermediate arrays.
With a random input of 500 characters, and maxLen at 20, I got 4207817 unique substrings. It took my computer (with MATLAB R2017a) 12 seconds to find these. Whether that is fast enough or not is up to you, but I would not bother further optimizing this.
input = 'ABCA';
maxLen = 4;
subsets = {};
for len = 1:maxLen
subs = cell(1,numel(input)-len+1);
for start = 1:numel(subs)
subs{start} = input(start:start+len-1);
end
subs = unique(subs);
subsets = [subsets,subs];
end
disp(subsets)
Output:
'A' 'B' 'C' 'AB' 'BC' 'CA' 'ABC' 'BCA' 'ABCA'
If it is important to preserve the order of the substrings, then add the 'stable' argument to the unique call:
subs = unique(subs,'stable');
For example, for input = 'AFCB';, the output without 'stable' is:
'A' 'B' 'C' 'F' 'AF' 'CB' 'FC' 'AFC' 'FCB' 'AFCB'
and with 'stable' it is:
'A' 'F' 'C' 'B' 'AF' 'FC' 'CB' 'AFC' 'FCB' 'AFCB'
I am a novice programmer that is primarily self-taught. I am new to MATLAB and relational mathematics. Currently, I am attempting to perform math operations between rows. I would like to normalize the exp by the corresponding con and then multiply by the constant.
This constant is a laboratory measurement that could be subject to change in future experments. Thus, I have given it a column.
Below is some sample code that I have generated to exemplify my problem and solution. I am trying to get from myTable to rTable.
I recognize my solution is very sloppy and there must be a way to perform these operations that is human-readable and uses less temporary variables. To put it shortly, there must be a simpler way.
rTable = table();
myTable = table(transpose(1:8), ...
transpose({'Con1', 'Con2', 'Exp1', 'Exp2',...
'Con1', 'Con2', 'Exp1', 'Exp2'}),...
transpose({'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'}),...
ones(8, 1) * 2,...
'VariableNames', {'Values' , 'Condition', 'Group', 'Constant'});
[r, c] = size(myTable)
a = myTable(strcmp(myTable.Group, 'A'), :);
b = myTable(strcmp(myTable.Group, 'B'), :);
aexp1 = a.Values(strcmp(a.Condition, 'Exp1'), :) / a.Values(strcmp(a.Condition, 'Con1'), :) * mean(a.Constant);
aexp2 = a.Values(strcmp(a.Condition, 'Exp2'), :) / a.Values(strcmp(a.Condition, 'Con2'), :) * mean(a.Constant);
bexp1 = b.Values(strcmp(b.Condition, 'Exp1'), :) / b.Values(strcmp(b.Condition, 'Con1'), :) * mean(b.Constant);
bexp2 = b.Values(strcmp(b.Condition, 'Exp2'), :) / b.Values(strcmp(b.Condition, 'Con2'), :) * mean(b.Constant);
aT = table(transpose({aexp1, aexp2}),...
transpose({'Exp1', 'Exp2'}),...
transpose({'A', 'A'}),...
transpose({2, 2,}),...
'VariableNames', {'Values', 'Condition', 'Group', 'Constant'});
bT = table(transpose({bexp1, bexp2}),...
transpose({'Exp1', 'Exp2'}),...
transpose({'B', 'B'}),...
transpose({2, 2,}),...
'VariableNames', {'Values', 'Condition', 'Group', 'Constant'});
rTable = [aT; bT]
Thank you for any input or suggestions. Perhaps, the data structure i am handling is poorly organized.
Here's one solution:
rTable = table();
myTable = table((1:8)',{'Con1', 'Con2', 'Exp1', 'Exp2','Con1', 'Con2', 'Exp1', 'Exp2'}',...
{'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'}','VariableNames', {'Values' , 'Condition', 'Group', 'Constant'})
conditionrows = contains(myTable.Condition,'Con')
exprows = contains(myTable.Condition,'Exp')
conditionTable = myTable(conditionrows,:)
expTable = myTable(exprows,:)
constant = 2
rValues = expTable.Values./conditionTable.Values * constant
rTable = expTable
rTable.Values = rValues
Since you are trying to get a table of only exprows, you separate your original table into a conditionTable and an expTable. I'm assuming you have one condition row for each exp row, and also that you have a good correspondence in the tables (if not it will require more processing), then you can calculate the rValue simply with a one line expression. The ./ is element-wise division. Also note that you can use ' to perform transpose in matlab (further note that if you want a column vector of 1:10 for example you have to do (1:10)', 1:10' gives you a row vector from 1 to 10 since 1:10' is interpreted as vector from 1 to the transpose of 10.
I have in Matlab the following cells containing various combinations of the letters a,b,c,d
%all combinations containing 'a' and/or 'b'
G1={'a', 'ab', 'ac', 'ad', 'abc', 'acd', 'abd', 'abcd', 'b', 'bc', 'bd', 'bcd'};
%all combinations containing 'c' and/or 'd'
G2={'c', 'ac', 'bc', 'cd', 'abc', 'acd', 'bcd', 'abcd', 'd', 'ad', 'bd', 'abd'};
%all combinations containing 'c'
G3={'c', 'ac', 'bc', 'cd', 'acd', 'abd', 'bcd', 'abcd'};
I then construct a cell all of dimension
allsize=size(G1,2)*size(G2,2)*size(G3,2);
containing all possible ways to match one element of G1 with one element of G2 with one element of G3.
all=cell(allsize,3);
count=0;
for h=1:size(G1,2)
for k=1:size(G2,2);
for j=1:size(G3,2);
count=count+1;
all(count,1)=G1(h);
all(count,2)=G2(k);
all(count,3)=G3(j);
end
end
end
Question: I want to construct a vector check of dimension allsize x 1 such that check(l)=1 if [all(l,1) contains a and all(l,2) contains c] or [all(l,1) contains b and all(l,2) contains d], and zero otherwise.
I am having problems in writing the if condition
check=zeros(allsize,1);
for l=1:allsize
%if [all(l,1) contains a and all(l,2) contains c] or [all(l,1) contains b and all(l,2) contains d]
check(l)=1;
%end
end
Could you kindly provide some help?
(For the if statement, always best to show what you tried rather than some pseudo code , however...)
Firstly using all as a variable name is bad - it's an important built-in function and one you may want to use... I've renamed it allG below. But you probably want something like this:
check(l) = (any(allG{l,1}=='a') && any(allG{l,2}=='c')) || ...
(any(allG{l,1}=='b') && any(allG{l,2}=='d'))
Note I haven't used an if statement, since the right hand side evaluates to a logical value (a true/false value) which can be generally used in the same way as 1 and 0...
Also above we're treating the strings as arrays of characters, so something like 'abcd'=='b' returns a [0 1 0 0] logical array... We then use any() to see if any of the values are 1 (true).
I have an array of cells, for example,
cells = {'a', 'b', 'c', d', 'e'};
which is inside a for loop of 1 to 5.
I want to create a variable from a to e depending on the loop index, as 1 to a, 2 to b...
When I try (i is the for index),
eval(cells{i}) = values; it gives me the error,
Undefined function or method 'eval' for input arguments of type 'a'
Here the answer:
eval(sprintf([cells{i} '=values;']))
And you can remove the ; if you want to see the display in command window.
In answer to your comment :
cells = {'a', 'b', 'c', 'd', 'e'};
values = 4;
i = 1;
eval(sprintf([cells{i} '=values;']))
This works perfectly fine on my computer, and i get no warning or error messages.
when calling eval, all arguments must be strings, so convert your cell elements to strings first.
eval([ cellstr(cells{i}) ' = values;']))