Addition of tow list with different list lengthes - list

I am trying to remove the strings from a list and then find the sum of the new list with a list which has smaller length.
I have written a code which does not work at 3-4 places. I have some question,
why does the if statement does not work propely?
How can I write the addition function for this kind of list with differnt lenght?
This is my code:
def remove_text_from_list(the_list):
z = []
for x in the_list:
if isinstance(x, float):
z.append(x)
return z
def add(a,b):
return a+b
x = []
list1=['s', 1.0, 2.0, 'a', 3.0, 4.0,'b', 5.0, 6.0,'c', 7.0, 8.0]
list2=[10.0, 20.0]
newlist=remove_text_from_list(list1)
for i in newlist:
for j in list2:
f = add(i,j)
final_list.append(f)
print(x)
The desired result should be like following:
final_list=[11,22,13,24,15,26,17,28]

Use a generator expression to create a generator that yields floats from list1. Use itertools.cycle to iterate over list2 repeatedly as needed. Use zip to pair the floats from list1 with the cycled items from list2 and add them together in a list comprehension.
>>> from itertools import cycle
>>> just_floats = (i for i in list1 if isinstance(i, float))
>>> [a+b for a, b in zip(just_floats, cycle(list2))]
[11.0, 22.0, 13.0, 24.0, 15.0, 26.0, 17.0, 28.0]

You return the list in the if-statement. If you do it at the end of the for-loop it should work:
def remove_text_from_list(the_list):
z = []
for x in the_list:
if isinstance(x, float):
z.append(x)
return z
But still x will not be your expected final_result but:
x = [11.0, 21.0, 12.0, 22.0, 13.0, 23.0, 14.0, 24.0, 15.0, 25.0, 16.0, 26.0, 17.0, 27.0, 18.0, 28.0]

Related

Scala: Sorting a list while keeping the position of placeholders

The problem I'm facing is sorting a List of Double values in Scala also containing some kind of placeholder values (Double.NaN in the example below. However, these can be set as required for the sorting to work.), which should keep their position after sorting.
Input:
val placeholder = Double.NaN
List(placeholder, 5.0, 2.0, placeholder, 4.0, 3.0, placeholder)
Output:
List(placeholder, 2.0, 3.0, placeholder, 4.0, 5.0, placeholder)
How can I sort Double values in a list without altering the position of placeholder values?
I'm searching for a solution to work with Scala 2, specifically 2.12
Thanks for your help!
One way is to sort the list and insert back the placeholders at right position.
This is not optimal, optimisation left to the reader as an exercise, but here's the idea:
val placeholder = Double.NaN
val list = List(placeholder, 5.0, 2.0, placeholder, 4.0, 3.0, placeholder)
val sorted = list.filterNot(_.isNaN).sorted
def insertSorted(in: List[Double], sorted: List[Double]): List[Double] = {
in match {
case Nil => Nil
case head :: tail =>
if (head.isNaN)
placeholder :: insertSorted(tail, sorted)
else
sorted.head :: insertSorted(tail, sorted.tail)
}
}
insertSorted(list, sorted)
// List(NaN, 2.0, 3.0, NaN, 4.0, 5.0, NaN)
This only works with NaN as placeholder. If using another value (like -1), regular comparison should be used.
Also, as raised in the comments, comparison on doubles can lead to surprises, use with caution.
This solution could also be written as a fold:
def sort(list: List[Double]): List[Double] = {
val (sorted, _) = list
.foldLeft((List.empty[Double], list.sorted)) { case ((result, sortedInput), n) =>
if (n.isNaN) (result :+ placeholder, sortedInput)
else (result :+ sortedInput.head, sortedInput.tail)
}
sorted
}
Again not optimal, but possibly the most straightforward if performance is not a high priority.
foldRight is stack safety
def sort(in: List[Double]): List[Double] = {
val sortedIn = in.filterNot(_.isNaN).sorted.reverse
val (result, _) = in.foldRight((List.empty[Double], sortedIn)) {
case (n, (result, list)) =>
if (n.isNaN) (placeholder :: result, list)
else (list.head :: result, list.tail)
}
result
}

How to compare sublists in List[List[Double]]

I have a List[List[Double]]
Ignoring the last element of each list with in outer list, I want to compare inner lists i.e. we have a
List(
List(0.1,0.5,0.3,0),
List(2.3,0.1,0.4,1),
List(0.1,0.5,0.3,1)
)
I want distinct list ignoring last element i.e.
List(
List(0.1,0.5,0.3,0),
List(2.3,0.1,0.4,1)
)
Here the 1st and last lists are similar ignoring the last elements.
kindly provide me some clue. As I am very new to scala.
Study the Standard Library. It's amazing the things you can find there.
List(List(0.1,0.5,0.3,0),List(2.3,0.1,0.4,1),List(0.1,0.5,0.3,1)).distinctBy(_.init)
//res0: List[List[Double]] = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0))
If you're on Scala 2.13+ please see #jwvh's solution, otherwise ...
You could traverse the list via foldLeft to assemble a new list of inner lists by checking against a Set of lists with distinct init:
val list = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0), List(0.1, 0.5, 0.3, 1.0))
list.foldLeft((List[List[Double]](), Set[List[Double]]())){ case ((ls, s), l) =>
val lInit = l.init
if (s.contains(lInit)) (ls, s) else (l :: ls, s + lInit)
}._1.reverse
// res1: List[List[Double]] = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0))
In case order of the resulting inner lists is unimportant, an alternative is to group the list by the inner list's init, followed by extracting the first inner list from the grouped Map values:
list.groupBy(_.init).map(_._2.head)
// res2: List[List[Double]] = List(List(2.3, 0.1, 0.4, 1.0), List(0.1, 0.5, 0.3, 0.0))

Checking for duplicates in a list Python

dataset:
raw_data = [[1, John, 23, 32], [1, Jane, 10, 20], [1, Max, 90, 70], [2, Harry, 32, 56]]
list = []
for i in raw_data:
if i[0] in list:
x = i[0] + 0.1
list.append(x)
else:
list.append(i[0])
I would actually like to obtain list = [1, 1.1, 1.2, 2]
However, my code is giving my list = [1, 1.1, 1.1, 2]
How can I run another loop in my list to add a 0.1 to a duplicated number?
You could use a dictionary to cache the increments:
cache = {}
result = []
for i in raw_data:
if i[0] in cache:
cache[i[0]] += 0.1
else:
cache[i[0]] = 1
result.append(cache[i[0]])
EDIT:
Using a defaultdict would save the condition inside the loop. Whether or not it's more elegant is in the eye of the beholder, though:
from collections import defaultdict
cache = defaultdict(lambda : 0.9)
result = []
for i in raw_data:
cache[i[0]] += 0.1
result.append(cache[i[0]])

How do I generate a List using tabulate who's entries are squared in Scala?

I'm new to Scala and I'm trying to generate a List using the tabulate() method.
I see that it's used this way and it works perfectly fine,
val myList = List.tabulate(10)(_ * 2)
but this doesn't
val myList = List.tabulate(10)(_ * _)
whereas, I got what I wanted by,
val myList = List.tabulate(10)(n => n * n)
Can I know why didn't the second example work?
An anonymous function represented with underscores is expected to have the same number of arguments as underscores. The particular overload of List.tabulate you are using (for one-dimension) expects a function with only argument, but you provide a function with two.
In other words _ * _ expands to (a, b) => a * b and it is not possible to represent a => a * a with just underscores.
Alternatively, you could use math.pow(_, 2) as your squaring function, but it returns Double instead of Int.
scala> List.tabulate(10)(math.pow(_, 2))
res0: List[Double] = List(0.0, 1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0, 81.0)

Multiply a list of lists by a list

i want to multiply a list of lists such as ([2,3,6],[3,4,9],[4,8,13]) by another list, which will also have the same number of lists as the first set of lists, i.e, the first list of lists may have 3 lists, each with a list of 5 numbers, but the second list will have 3 numbers, each multiplying the elements of the rows of the first list. e.g
([2,3,6],[3,4,9],[4,8,13]) with [2,3,4]
would result in
([4,6,12],[9,12,27],[16,32,52])
so far i have
sol = [inv[i]*bb[i] for i in range(len(inv[i]))]
return sol
where inv[i] is my list of lists and bb is my list.
i want this so that it can be done for any lenght of list in bb, and inv[i] as long as they are both the same length
thanks guys
UPDATE:
i added in pound's solution and fiddled around a bit
it now prints
[20.0, -9.0, -3.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
[3.0, -2.0, -0.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
[-8.0, 4.0, 1.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
[40.0, -18.0, -6.0]
for this code:
print (inv[i])
sol = []
for i, item in enumerate(inv):
sol.append(map(lambda x: x*bb[i], item))
print sol[i]
how do i get rid of the bullshit stuff and keep the last 3 lines seen only?
big = [[2,3,6],[3,4,9],[4,8,13]]
small = [2,3,4]
res = []
for i, item in enumerate(big):
res.append(map(lambda x: x*small[i], item))
print res
Output:
[[4, 6, 12], [9, 12, 27], [16, 32, 52]]
import itertools
L = [[2,3,6],[3,4,9],[4,8,13]]
M = [2,3,4]
[[i*j for i,j in zip(subl, subm)] for subl, subm in zip(L, itertools.cycle([M]))]
Ouptut:
Out[101]: [[4, 9, 24], [6, 12, 36], [8, 24, 52]]
Without itertools:
answer = []
for subl in L:
temp = []
for i in range(len(subl)):
temp.append(subl[i] * M[i])
answer.append(temp)
Output:
In [103]: answer
Out[103]: [[4, 9, 24], [6, 12, 36], [8, 24, 52]]
Use numpy library:
import numpy as np
list1 = np.array([[2,3,6],[3,4,9],[4,8,13]])
list2 = np.array([2,3,4])
result = list1 * list2.transpose()
result_list = result.tolist()
Or without numpy:
list1 = [[2,3,6],[3,4,9],[4,8,13]]
list2 = [2,3,4]
result_list = list1[:]
for i in range(len(list1)):
result_list[i] = [x * list2[i] for x in result_list[i]]