Creating a lists of sums from a list - list

Is there a groovier way of doing this? That is, create a new list from the sum of groups of 3 numbers from the original list.
myList = [1,2,3,4,5,6,7,8,9]
newList = []
while (myList.size > 0) {
newList.add(myList.pop() + myList.pop() + myList.pop())
}
println newList.reverse()
[6, 15, 24]

How about this:
myList.collate(3).collect {it.sum()}
or with just a fine use of spread operator *
myList.collate(3)*.sum()

You can group the list into sublists of 3 elements with collate:
groovy:000> myList = [1,2,3,4,5,6,7,8,9]
===> [1, 2, 3, 4, 5, 6, 7, 8, 9]
groovy:000> myList.collate(3)
===> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Then sum each sublist; the sum can be done with inject:
groovy:000> myList.collate(3)*.inject(0) { sum, i -> sum + i }
===> [6, 15, 24]
or just use this convenience method sum
groovy:000> myList.collate(3)*.sum()
===> [6, 15, 24]

Related

Nested sum in Erlang

I have a doubt how can I add the numbers of list including the ones that are on a nested list, for example:
test:nestedSum([1, [2, 3], [4, 5, 6], 7]).
⇒ 28
So far I got this:
nestedSum(L) -> nestedSum(L, 0).
nestedSum([H|T], Acc) ->
nestedSum(T, H + Acc);
nestedSum([], Acc) ->
Acc.
which only works:
test:nestedSum([1, 2, 3, 4, 5, 6, 7]).
⇒ 28
but it does not sum the numbers that are in the nested sum, How can I do it?
You just need to add one clause to the nestedSum/2 function for the case when the head of the list is a list:
% Add this before the two existing clauses.
nestedSum([H|T], Acc) when is_list(H) ->
nestedSum(T, nestedSum(H) + Acc);
With this, your function can now handle any nested list:
1> a:nestedSum([1, [2, 3], [4, 5, 6], 7]).
28
2> a:nestedSum([1, [2, 3], [4, 5, 6], 7, [8, [[[9, [[[[[[10]]]]]]]]]]]).
55
You could use lists:flatten:
nestedSum(L) -> nestedSum(lists:flatten(L), 0).
.
.
Reducing a list is often a one-liner:
lists:foldl(fun(X,Sum) -> X + Sum end, 0, lists:flatten([1, [2, 3], [4, 5, 6], 7])).

Create a function genSet() that takes in a list of numbers and returns a sorted set in python

I am new to python and trying to solve this example on pyschool
I need to write a function,
a) that takes a list of numbers
b) removes duplicates from the list
c) returns a sorted set:
In python, example :
>>> genSet([5,4,8,4,9,8])
[4, 5, 8, 9 ]
>>> genSet([3,-2,-1,-1,3,-2,0])
[-2, -1, 0, 3 ]
Removing Duplicates:
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]
Sort the List:
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]
Now you could write your custom function, that removes duplicates and sort.
The following code snippet works:
def genSet(clist):
t = list(set(clist))
return sorted(t)
if __name__ == "__main__":
print genSet([5,4,8,4,9,8])
print genSet([3,-2,-1,-1,3,-2,0])
If you want to iterate over multiple list try this:
a = [
[5,4,8,4,9,8],
[3,-2,-1,-1,3,-2,0]
]
for aa in a:
print genSet(aa)
set will automatically remove duplicates and sorted will sort the list.
def genSet(l):
return (sorted(set(l)))

Why the map function doesn't return the list without duplicate elements?

I have this list:
list1 = [1, 1, 1, 3, 3, 3, 56, 6, 6, 6, 7]
And I wat to get rid of duplicate values. The code for the map function is taken from here.
this is the complete testing code:
list1 = [1, 1, 1, 3, 3, 3, 56, 6, 6, 6, 7]
list2 = []
map(lambda x: not x in list2 and list2.append(x), list1)
print(list2)
list2 = []
[list2.append(c) for c in list1 if c not in list2]
print(list2)
list2 = []
for c in list1:
if c not in list2:
list2.append(c)
print(list2)
In Python 2.7 is prints:
[1, 3, 56, 6, 7]
[1, 3, 56, 6, 7]
[1, 3, 56, 6, 7]
In Python 3.4 it prints:
[]
[1, 3, 56, 6, 7]
[1, 3, 56, 6, 7]
Why the map function returns an empty list in Python3?
Because in python-3.x a map is not evaluate immediately. It works as a generator where elements are generated on the fly by need: this can be more efficient since it is possible you for instance only need the first three elements so why would you calculate all elements? So as long as you do not materialize the output of map in a way, you have not really calculated the map.
You can for instance use list(..) to force Python to evaluate the list:
list(map(lambda x: not x in list2 and list2.append(x), list1))
In that case python-3.x will generate the same result for list2.

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