convert nested list to int or str - python

I have the following list structure:
the_given_list = [[[1],[2],[3]],[[1],[2],[3]]]
Indeed len(the_given_list) returns 2.
I need to make the following list:
the_given_list = [[1,2,3],[1,2,3]]
How to do it?

[sum(x, []) for x in the_given_list]
Flatten the first-order element in the_given_list.
the_given_list = [sum(x, []) for x in the_given_list]
print(the_given_list)

To explain the above answer https://stackoverflow.com/a/57369395/1465553, this list
[[[1],[2],[3]],[[1],[2],[3]]]
can be seen as
[list1, list2]
and,
>> sum([[1],[2],[3]], [])
[1,2,3]
>>> sum([[1],[2],[3]], [5])
[5, 1, 2, 3]
Since the second argument to method sum defaults to 0, we need to explicitly pass empty list [] to it to overcome type mismatch (between int and list).
https://thepythonguru.com/python-builtin-functions/sum/

Use itertools.chain
In [15]: from itertools import chain
In [16]: [list(chain(*i)) for i in the_given_list]
Out[16]: [[1, 2, 3], [1, 2, 3]]

the_given_list = [ [ s[0] for s in f ] for f in the_given_list ]

Another solution:
the_given_list = [[[1],[2],[3]],[[1],[2],[3]]]
print([[j for sub in i for j in sub] for i in the_given_list])
Gives me:
[[1, 2, 3], [1, 2, 3]]
Check the original answer on list flattening:
https://stackoverflow.com/a/952952/5501407

Related

Python: how to remove single quote on first and last element of list

i have a list that goes like this ['1,2'] and i need to turn it into [1, 2]. Using int() won't work. Is there a way to add a single quote and then use int(), a way to remove a single quote or is there just a better way to do this?
here is the code that i am using
a_list = genres_selected.split()
map_object = map(int, a_list)
genres_selected_use = list(map_object)
genres_selected will always be different as it is being passed through ajax form
but here it is "1, 2"
I think you are looking to remove the string and convert it into an integer. Since the list has a string, you want to split the string using comma delimiter.
list_vals = ['1,2,3,4,5,6']
map_object = map(int, list_vals[0].split(','))
print (list(map_object))
The output of this will be:
[1, 2, 3, 4, 5, 6]
However, if your list has multiple strings of integers in single quotes, you can do:
my_list = ['1,2','3,4','5,6']
num_list = [[int(i) for i in num.split(',')] for num in my_list]
print (num_list)
The output of this will be:
[[1, 2], [3, 4], [5, 6]]
lst = ['1,2', '3,4,5']
new_list = []
for item in lst:
new_list.extend([int(num) for num in item.strip().split(',')])
print(new_list)
>>> [1, 2, 3, 4, 5]
One Liner Version
lst = ['1,2', '3,4,5']
print([int(item) for sublist in map(lambda item: item.split(','), lst) for item in sublist])
>>> [1, 2, 3, 4, 5]

How to get a max value of each matrix row and save them in another list?

I have got the such matrix as:
matrix = [ [0,0,2],[1,0,1],[2,1,0] ]
And I would like to get a list like:
[2,1,2]
the compare is column to each column, so matrix[0][0] compared with matrix[1][0] and matrix[2][0], thanks
another example like :
[[0,0,2],[1,0,1],[2,1,0],[2,1,3]]
And I would like to get a list like:
[2,1,3]
An alternative to List Comprehension, using map :
>>> list(map(max, l))
#driver values :
IN : l = [ [0,0,2],[1,0,1],[2,1,0] ]
OUT : [2, 1, 2]
EDIT : The above finds max for each inner-list. The same for the desired behaviour by the OP (column-wise) :
>>> list(map(max, zip(*l)))
#driver values :
IN : l = [[0,0,2],[1,0,1],[2,1,0],[2,1,3]]
OUT : [2, 1, 3]
If you are happy to use a 3rd party library, numpy provides one way.
This assumes your list elements have the same length.
import numpy as np
A = np.array([[0,0,2],[1,0,1],[2,1,0],[2,1,3]])
res = A.max(axis=0)
# array([2, 1, 3])
lst = [ [0,0,2],[1,0,1],[2,1,0] ]
print [max(i) for i in lst]
Combination of list comprehension, zip and reduction should also deliver required result:
matrix = [[0,0,2],[1,0,1],[2,1,0],[2,1,3]]
max_cols = [max(list(i)) for i in zip(*matrix)]
max_cols has max values of matrix columns - [2, 1, 3]
As others have said you can use
>>> [max(i) for i in a]
[2, 1, 2]
But there is also this for the opposite of what you want
>>> [min(i) for i in a]
[0, 0, 0]

Removing duplicates from a list but returning the same list

I need to remove the duplicates from a list but return the same list.
So options like:
return list(set(list))
will not work for me, as it creates a new list instead.
def remove_extras(lst):
for i in lst:
if lst.count(i)>1:
lst.remove(i)
return lst
Here is my code, it works for some cases, but I dont get why it does not work for remove_extras([1,1,1,1]), as it returns [1,1] when the count for 1 should be >1.
You can use slice assignment to replace the contents of the list after you have created a new list. In case order of the result doesn't matter you can use set:
def remove_duplicates(l):
l[:] = set(l)
l = [1, 2, 1, 3, 2, 1]
remove_duplicates(l)
print(l)
Output:
[1, 2, 3]
You can achieve this using OrderedDict which removes the duplicates while maintaining order of the list.
>>> from collections import OrderedDict
>>> itemList = [1, 2, 0, 1, 3, 2]
>>> itemList[:]=OrderedDict.fromkeys(itemList)
>>> itemList
[1, 2, 0, 3]
This has a Runtime : O(N)

mapping the append function to a list

I want to do the following elegantly. I have a list:
list1 = [[1,2],[3,1,4,7],[5],[7,8]]
I'd like to append the number 1 to each element of the list, so that I have
list1 = [[1,2,1],[3,1,4,7,1],[5,1],[7,8,1]]
I'm trying to map this via
map(list.append([1]), vectors)
but this returns the error append() takes exactly one argument (0 given) and if I just try append([1]) (without list.), I get NameError: global name 'append' is not defined. I guess I could do it with a loop, but this seems more elegant, is there a way to map this correctly?
Here is a several ways to implement what you want:
More readable and classic way
for el in list1:
el.append(1)
List comprehension
list1 = [el + [1] for el in list1]
Generators:
list1 = (el + [1] for el in list1)
Map
list1 = map(lambda el: el + [1], list1)
What to use?
It depends on you own situation and may depends on execution speed optimizations, code readability, place of usage.
Map is a worst choice in case of readability and execution speed
For is a fastest and more plain way to do this
Generators allows you to generate new list only when you really need this
List comprehension - one liner for classic for and it takes advantage when you need quickly filter the new list using if
i.e. if you need only add element to each item - for loop is a best choice to do this, but if you need add item only if item > 40, then you may consider to use List comprehension.
For example:
Classic For
x = 41
for el in list1:
if x > 40:
el.append(x)
List comprehension
x = 1
list1 = [el + [x] for el in list1 if x > 40]
as #jmd_dk mentioned, in this sample is one fundamental difference: with simple for you can just append to an existing object of the list which makes much less impact to execution time and memory usage. When you use List comprehension, you will get new list object and in this case new list object for each item.
Try a list comprehension, taking advantage of the fact the adding lists concats them together.
new_list = [l + [1] for l in list1]
You can simply do
list1 = [[1,2],[3,1,4,7],[5],[7,8]]
for el in list1:
el.append(1)
map(lambda x: x + [1], list1)
you mean this?
list.append() have NO return (mean always return None)
With list comprehension and append, you can do:
list1 = [[1, 2], [3, 1, 4, 7], [5], [7, 8]]
[item.append(1) for item in list1]
print(list1) # Output: [[1, 2, 1], [3, 1, 4, 7, 1], [5, 1], [7, 8, 1]]
Output:
>>> list1 = [[1, 2], [3, 1, 4, 7], [5], [7, 8]]
>>> [item.append(1) for item in list1]
[None, None, None, None]
>>> list1
[[1, 2, 1], [3, 1, 4, 7, 1], [5, 1], [7, 8, 1]]
You may also use extend like this:
[item.extend([1]) for item in list1]
print(list1) # Output: [[1, 2, 1], [3, 1, 4, 7, 1], [5, 1], [7, 8, 1]]

Turning a list into nested lists in python

Possible Duplicate:
How can I turn a list into an array in python?
How can I turn a list such as:
data_list = [0,1,2,3,4,5,6,7,8]
into a list of lists such as:
new_list = [ [0,1,2] , [3,4,5] , [6,7,8] ]
ie I want to group ordered elements in a list and keep them in an ordered list. How can I do this?
Thanks
This groups each 3 elements in the order they appear:
new_list = [data_list[i:i+3] for i in range(0, len(data_list), 3)]
Give us a better example if it is not what you want.
This assumes that data_list has a length that is a multiple of three
i=0
new_list=[]
while i<len(data_list):
new_list.append(data_list[i:i+3])
i+=3
Something like:
map (lambda x: data_list[3*x:(x+1)*3], range (3))
Based on the answer from Fred Foo, if you're already using numpy, you may use reshape to get a 2d array without copying the data:
import numpy
new_list = numpy.array(data_list).reshape(-1, 3)
new_list = [data_list[x:x+3] for x in range(0, len(data_list) - 2, 3)]
List comprehensions for the win :)
The following function expands the original context to include any desired list of lists structure:
def gen_list_of_lists(original_list, new_structure):
assert len(original_list) == sum(new_structure), \
"The number of elements in the original list and desired structure don't match"
list_of_lists = [[original_list[i + sum(new_structure[:j])] for i in range(new_structure[j])] \
for j in range(len(new_structure))]
return list_of_lists
Using the above:
data_list = [0,1,2,3,4,5,6,7,8]
new_list = gen_list_of_lists(original_list=data_list, new_structure=[3,3,3])
# The original desired outcome of [[0,1,2], [3,4,5], [6,7,8]]
new_list = gen_list_of_lists(original_list=data_list, new_structure=[2,3,3,1])
# [[0, 1], [2, 3, 4], [5, 6, 7], [8]]
The below one is more optimized and quite straightforward.
data_list = [0,1,2,3,4,5,6,7,8]
result =[]
i=0
while i <(len(data_list)-2):
result.append(data_list[i:i+3])
i+=3
print(result)
**output**
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Here is a generalized solution
import math
data_list = [0,1,2,3,4,5,6,7,8]
batch_size=3
n_batches=math.ceil(len(data_list)/batch_size)
[data_list[x*batch_size:min(x*batch_size+batch_size,len(data_list))]
for x in range(n_batches)]
It works even if the last sublist is not the same size as the rest (<batch_size)
Do you have any sort of selection criteria from your original list?
Python does allow you to do this:
new_list = []
new_list.append(data_list[:3])
new_list.append(data_list[3:6])
new_list.append(data_list[6:])
print new_list
# Output: [ [0,1,2] , [3,4,5] , [6,7,8] ]

Categories