Python 3 list comprehension in list of lists to convert types - python-3.x

Consider the following list of lists:
list1 = [['1.1', '1.2', '1.3'], ['2.1', '2.2', '2.3'], ...]
To comprehend a list of strings to convert them to floats one could use
list1[0] = [float(i) for i in list1[0]]
But my attempt to comprehend a list of lists of floats didn't quite work:
list1 = [[float(j) for j in list1[i]] for i in list1]
due to
TypeError: list indices must be integers or slices, not list
Is there a way to do this sort of list comprehension without using loops explicitly?

[[float(j) for j in i] for i in list1]
shall do it

Related

Matching character lists of unequal length

I want to match two lists from which one list is smaller while other is a bigger one. If a match occurs between two lists then put the matching element in a new list at the same index instead of putting it another index. You can understand my question from the code given below:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
elem2 = list1[ind]
elem1 = list2[ind][0:2]
if elem1 in list2:
matchlist.append(list1[ind])
Obtained output
>>> matchlist
['KNJ', 'NJK', 'JNJ']
Desired Output
>>> matchlist
['AFG', 'KNJ', 'JNJ', 'NJK']
Is there a way to get the desired output?
Use a nested loop iterating over the 3-char list. When an item in that list contains the current item in the 2-char list, append it and break out of the inner loop:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
for item in list2:
if list1[ind] in item:
matchlist.append(item)
break
Given the question doesn't specify any constraints, in a more pythonic way, using a list comprehension:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist=[e2 for e1 in list1 for e2 in list2 if e2.startswith(e1)]
produces
['AFG', 'KNJ', 'JNJ', 'NJK']

Python map vs List comprehension Time Complexity

a = [1,2,3,4,5]
All the integers in this array can be converted into strings individually in the following 3 ways.
1) Using Str
a=[1,2,3,4,5]
for i in range(len(a)):
a[i] = str(a[i])
print(type(a[0]))
2) Using Map
a=[1,2,3,4,5]
a = list(map(str,a))
print(type(a[0]))
3) Using List Comprehension
a=[1,2,3,4,5]
a = [str(i) for i in a]
print(type(a[0]))
Can I know what is the time complexity in all the 3 cases to find out which method is efficient? I am a bit confused about this.
Thanks in advance!

Converting string to float with error handling inside a list comprehension

Consider the following list of lists:
list1 = [['1.1','1.2'],['2.1', '2.2'],[''],...]
This list contains lists with empty strings. To convert all strings in this list of lists to floats one could use list comprehension, such as:
[[float(j) for j in i] for i in list1]
(thanks to).
But there is one problem with the lists containing empty strings - they cause an exception:
ValueError: could not convert string to float:
Is there a way to use this kind of list comprehension without using loops explicitly?
Use an if condition inside the inner list comprehension to ignore empty strings:
[[float(j) for j in i if i] for i in list1]
if i will test the "truthiness" of strings. This will only return False for empty strings, so they are ignored.
Or, if you want to be more robust about it, use a function to perform the conversion with exception handling:
def try_convert(val):
try:
return float(val)
except ValueError, TypeError:
pass
[[float(z) for z in (try_convert(j) for j in i) if z] for i in list1]

Please enumerate all kinds of comprehensions in Python 3

So far, I've learned about
list
set
dictionary
generator
comprehensions. Are there any other iterables that can be ''comprehended''? I'm mostly interested in Python 3.
my_dict = {i:char for i,char in enumerate("Hello, world!")}
my_list = [i**2 for i in range(10)]
my_set = {i**2 for i in range(10)}
my_generator = (i**2 for i in range(10))
In terms of just comprehensions, there aren't any more that I'm aware of. You could of course use a list/generator comprehension within (say) a tuple constructor to create a (in this case) tuple. But that's not a generator per se

Python list comprehension - conditional for-loop

I've written some code like so which works fine and does what I want:
#!/usr/bin/env python3
myList = [[0], [1, 2], {'val': [3, 4, 5]}, [6]]
flat1 = []
for sublist in myList:
if type(sublist) is list:
for item in sublist:
flat1.append(item)
else:
for item in sublist['val']:
flat1.append(item)
print(flat1)
So it's a twist on the standard nested list flattening. The twist is that some nested items are not actually lists, but rather dictionaries with a 'val' (and we want the items in the 'val' list in those cases).
I'm trying to make it into a list comprehension. Here is what I've tried:
flat2 = [item for sublist in myList for item in sublist if type(sublist) is list else for item in sublist['val']]
print(flat2)
I get the following error with a caret pointing to the 'else'.
SyntaxError: invalid syntax
And yes what I've written into the list comprehension seems like nonsense and no doubt the compiler has no idea what I'm trying to do.
Is it possible to do what I'm trying to do with a list comprehension?
[item
for sublist in myList
for item in (sublist if type(sublist) is list else sublist['val'])
]
First off, I recommend against this approach. Why do you want to take what is already pretty readable and condense it so that it's unreadable?
flattened = [i for iterable in
(j if type(j) is list else j["val"] for j in myList)
for i in iterable]
Update after reading comment
One nice thing to do is to break out the list comprehension into two steps:
iterables = (j if type(j) is list else j["val"] for j in myList)
flattened = [i for iterable in iterables for i in iterable]
This is more readable -- and no less computationally efficient. Note the use of parentheses in iterables -- which makes it a generator that is lazily evaluated. That way, if myList is really long, you're still only reading through it once and you don't have to wait to read all the way through before proceeding.

Resources