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