Python- converting to float using map() - python-3.x

If I have a list like the one given below, and want to convert the given integers to float, is there a way I can do it with map()?
my_list=[['Hello', 1 , 3],['Hi', 4 , 6]]

It's ugly, but yeah, it can be done:
my_list=[['Hello', 1 , 3],['Hi', 4 , 6]]
print(list(map(lambda lst: list(map(lambda x: float(x) if type(x) == int else x, lst)), my_list)))
# Output: [['Hello', 1.0, 3.0], ['Hi', 4.0, 6.0]]
EDIT
I personally prefer list comprehension in most cases as opposed to map/lambda, especially here where all the conversions to lists are annoying:
print([
[float(x) if type(x) == int else x for x in lst]
for lst in my_list
])
EDIT 2
And finally, an in-place solution that uses good old for loops:
for lst in my_list:
for i, item in enumerate(lst):
if type(item) == int:
lst[i] = float(item)
print(my_list)

If you are going to use map, you can increase readability by using it with previously defined functions. First make a function which converts an object to a float if possible, and leaves it alone if not:
def toFloat(x):
try:
return float(x)
except:
return x
Then you can map this across a list like:
def listToFloats(items):
return list(map(toFloat,items))
And then map this last function across a list of lists:
def listsToFloats(lists):
return list(map(listToFloats,lists))
For example:
>>> my_list=[['Hello', 1 , 3],['Hi', 4 , 6]]
>>> listsToFloats(my_list)
[['Hello', 1.0, 3.0], ['Hi', 4.0, 6.0]]

Related

How do I convert a list of tuples and number to a tuple

Hi Stackoverflow geeks,
I have this list:
[(('Male', 'White'), 6488)]
& I want to convert it to a tuple like this:
('Male', 'White', 6488)
I appreciate if you help me with the code.
This is a generalised solution to flatten lists that contain a possible combination of iterables and non-iterables of various types:
import functools
from typing import Any, Iterable, List
def ext(x: List, y: Any) -> List:
"""
Returns x, extended or appended to include the individual constituents of y.
x is always a list. y may or may not be.
"""
# Because strings are iterable, we don't want them to be broken down
# into individual characters - so we check that y is iterable but not a
# string.
if isinstance(y, Iterable) and not isinstance(y, str):
x.extend(y)
else:
x.append(y)
return x
Use the above function with functools.reduce to work your way through the original iterable, accumulating its contents into a single list.
You provide [] as an initial value for x passed into ext, to guarantee that it is always a list for the purposes of ext. Once you have that list, convert it into a tuple to give you your desired result.
Trying this on your original problem - arr1 below, you need to run this approach twice, because your original iterable only contains one iterable of its own:
arr1 = [('Male', 'White'), 6488]
result1 = tuple(functools.reduce(ext, arr1, []))
print (result1)
# Result -> (('Male', 'White'), 6488)
result1 = tuple(functools.reduce(ext, result1, []))
print(result1)
# Result -> ('Male', 'White', 6488)
Trying it on a more complex object:
arr2 = [('foo'), 'bar', ['bleep', 'bloop'], {'a': 1, 'b': 2}]
result2 = tuple(functools.reduce(ext, arr2, []))
print(result2)
# Result -> ('foo', 'bar', 'bleep', 'bloop', 'a', 'b')
Note that with dictionaries, you only get the keys back. If you want key/value pairs, you'll need to add a specific guard for this, like so:
def ext2(x: List, y: Any) -> List:
"""
Reworking ext to deal differently with dictionaries in the original iterable.
"""
if isinstance(y, Iterable) and not isinstance(y, str):
if isinstance(y, dict):
x.extend(y.items())
else:
x.extend(y)
else:
x.append(y)
return x
Trying it again on the last example::
arr2 = [('foo'), 'bar', ['bleep', 'bloop'], {'a': 1, 'b': 2}]
result3 = tuple(functools.reduce(ext2, arr2, []))
print(result3)
# Result -> ('foo', 'bar', 'bleep', 'bloop', ('a', 1), ('b', 2))

List comprehension flat list?

I have the following toy function:
def foo(a):
return [a+5]
And I am running the following code:
my_lst = [foo(x) for x in range(10) if x%2 == 0]
Getting:
[[5], [7], [9], [11], [13]]
But need:
[5,7,9,11,13]
But I want to get a plain list, not a list of lists.
How can I do it without itertools.chain.from_iterable(my_lst) but with list comprehension?
What is the best practice? itertools or list comprehension in this case?
Please advice.
I have tried:
[j[0] for j in [foo(x) for x in range(10) if x%2 == 0]]
Should I do it like this or there is a better way?
With list comprehension, it's done using two for loops:
my_lst = [subx for x in range(10) if x%2 == 0 for subx in foo(x)]
Also if you have a list of lists of one elements, you can "transpose" after the fact the list using zip:
bad_lst = [foo(x) for x in range(10) if x%2 == 0]
[my_lst] = zip(*bad_lst)
Or you can "transpose" using a list comprehension combined with list unpacking as well if you truly want a list as output and not a tuple:
bad_lst = [foo(x) for x in range(10) if x%2 == 0]
my_lst = [x for [x] in bad_lst]
alternatively to Laernes answer, you can also use itertools as :
list(itertools.chain(*[foo(x) for x in range(10) if x%2 == 0]))
or
list(itertools.chain.from_iterable([foo(x) for x in range(10) if x%2 == 0]))
More options here:
Your function should return a number, not a list:
def foo(a):
return a+5

How to multiply 2 input lists in python

Please help me understand how to code the following task in Python using input
Programming challenge description:
Write a short Python program that takes two arrays a and b of length n
storing int values, and returns the dot product of a and b. That is, it returns
an array c of length n such that c[i] = a[i] · b[i], for i = 0,...,n−1.
Test Input:
List1's input ==> 1 2 3
List2's input ==> 2 3 4
Expected Output: 2 6 12
Note that the dot product is defined in mathematics to be the sum of the elements of the vector c you want to build.
That said, here is a possibiliy using zip:
c = [x * y for x, y in zip(a, b)]
And the mathematical dot product would be:
sum(x * y for x, y in zip(a, b))
If the lists are read from the keyboard, they will be read as string, you have to convert them before applying the code above.
For instance:
a = [int(s) for s in input().split(",")]
b = [int(s) for s in input().split(",")]
c = [x * y for x, y in zip(a, b)]
Using for loops and appending
list_c = []
for a, b in zip(list_a, list_b):
list_c.append(a*b)
And now the same, but in the more compact list comprehension syntax
list_c = [a*b for a, b in zip(list_a, list_b)]
From iPython
>>> list_a = [1, 2, 3]
>>> list_b = [2, 3, 4]
>>> list_c = [a*b for a, b in zip(list_a, list_b)]
>>> list_c
[2, 6, 12]
The zip function packs the lists together, element-by-element:
>>> list(zip(list_a, list_b))
[(1, 2), (2, 3), (3, 4)]
And we use tuple unpacking to access the elements of each tuple.
From fetching the input and using map & lambda functions to provide the result. If you may want to print the result with spaces between (not as list), use the last line
list1, list2 = [], []
list1 = list(map(int, input().rstrip().split()))
list2 = list(map(int, input().rstrip().split()))
result_list = list(map(lambda x,y : x*y, list1, list2))
print(*result_list)
I came out with two solutions. Both or them are the ones that are expected in a Python introductory course:
#OPTION 1: We use the concatenation operator between lists.
def dot_product_noappend(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c = list_c + [list_a[i]*list_b[i]]
return list_c
print(dot_product_noappend([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
#OPTION 2: we use the append method
def dot_product_append(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c.append(list_a[i]*list_b[i])
return list_c
print(dot_product_append([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
Just note that the first method requires that you cast the product of integers to be a list before you can concatenate it to list_c. You do that by using braces ([[list_a[i]*list_b[i]] instead of list_a[i]*list_b[i]). Also note that braces are not necessary in the last method, because the append method does not require to pass a list as parameter.
I have added the two function calls with the values you provided, for you to see that it returns the correct result. Choose whatever function you like the most.

Everytime I run this code it says that numpy.ndarray has not attribute 'index'

When I run this code it returns that the numpy.ndarray object has no attributes. I'm trying to write a function that in case the number given is in the array will return with the position of that number in the array.
a = np.c_[np.array([1, 2, 3, 4, 5])]
x = int(input('Type a number'))
def findelement(x, a):
if x in a:
print (a.index(x))
else:
print (-1)
print(findelement(x, a))
Please use np.where instead of list.index.
import numpy as np
a = np.c_[np.array([1, 2, 3, 4, 5])]
x = int(input('Type a number: '))
def findelement(x, a):
if x in a:
print(np.where(a == x)[0][0])
else:
print(-1)
print(findelement(x, a))
Result:
Type a number: 3
2
None
Note np.where returns the indices of elements in an input array where
the given condition is satisfied.
You should check out np.where and np.argwhere.

Sorted insert on a python list

Good morning everybody,
Here is my function that is supposed to make a recursive sorted insertion of a couple of data:
def sorted_insert(w_i,sim,neighbors):
if neighbors==[]:
neighbors.append((w_i,sim))
elif neighbors[0][1]<sim:
neighbors.insert(0,(w_i,sim))
else:
sorted_insert(w_i,sim,neighbors[1:])
return neighbors
The problem is, this function doesn't insert values in the middle, here is a series of insertions :
>>> n=[]
>>> n=sorted_insert("w1",0.6,n)
>>> n=sorted_insert("w1",0.3,n)
>>> n=sorted_insert("w1",0.5,n)
>>> n=sorted_insert("w1",0.8,n)
>>> n=sorted_insert("w1",0.7,n)
>>> n
[('w1', 0.8), ('w1', 0.6)]
Is there someone that can correct my function ?
Thanks in advance.
This should work.
def sorted_insert(w_i,sim,neighbors, i=0):
if len(neighbors) == i or sim > neighbors[i][1]:
neighbors.insert(i, (w_i,sim))
else:
sorted_insert(w_i,sim,neighbors, i+1)
n=[]
sorted_insert("w1",0.6,n)
sorted_insert("w1",0.3,n)
sorted_insert("w1",0.5,n)
sorted_insert("w1",0.8,n)
sorted_insert("w1",0.7,n)
print n
# [('w1', 0.8), ('w1', 0.7), ('w1', 0.6), ('w1', 0.5), ('w1', 0.3)]

Resources