Transform a single list into a nested list - python

I want to transform a single array [1,1,1,1,1,1....] into a nested list(?) or multiple arrays like [[1],[1],[1],[1],[1]...]
My code is returning this problem:
ValueError: all the input arrays must have same number of dimensionsand I believe it's because of that.

Use a list comprehension:
unnested_l = [1]*20
nest_l = [[x] for x in unnested_l]
nest_l == [[1], [1], ...] # 20 times

Since your question says "array", I am providing a solution using NumPy's newaxis
import numpy as np
arr = np.array([1,1,1,1,1,1])
arr = arr[:, None]
print (arr)
# [[1]
# [1]
# [1]
# [1]
# [1]
# [1]]

Check this
l=[1,1,1,1,1,1,1]
res=[]
for x in l:
res.append([x])
print(res)
Output:
[[1],[1],[1],[1],[1],[1],[1]]

Related

Get choose specific elements from an array based on list of index

A=np.array([ [7,8],[7,9],[3,4],[5,4],[3,4],[5,6] ])
indicesB=np.array([ [1] ,[1] ,[1] ,[2] ,[1] ,[2] ])
how can i get all the elements in A if the same position elements in indices B= 1?
for example,
if i want indicesB= 2,then i get[5,4],[5,6]
if i want indicesB= 1,then i get[7,8],[7,9],[3,4],[3,4]
What I want is something like this
Y=np.array([[7,8],[3,4],[3,4],[3,4],[3,4],[3,4]])
X=np.array([[1],[1],[1],[1],[1],[2]])
for x in range(1,3):
for i in range(6):
if X[i]==x:
print('the indice is ', x,Y[i])
how cccan i make it simple using numpy?
If I understand right this code might helps you:
new_list = []
for i,j in zip(A, indicesB):
el = i[:j[0]].tolist()
new_list.append(el)
If you need an array instead of list you should use i[:j[0]] without .tolist() and after loop change type new_list to array like that:
new_list = np.array(new_list)
Can you use dict ? that way you can call perticular key dict[1] and you will receive np.array.
import numpy as np
dic = {s:[] for s in set(np.concatenate([x.ravel() for x in X]))}
[dic[j.tolist()[0]].append(i.tolist()) for i,j in zip(A, B)]
np.array(dic[2]) #or np.array(dic[int(input())])
Output:
array([[5, 4],
[5, 6]])

how to avoid List assignment index out of range [duplicate]

How do I create an empty list that can hold 10 elements?
After that, I want to assign values in that list. For example:
xs = list()
for i in range(0, 9):
xs[i] = i
However, that gives IndexError: list assignment index out of range. Why?
Editor's note:
In Python, lists do not have a set capacity, but it is not possible to assign to elements that aren't already present. Answers here show code that creates a list with 10 "dummy" elements to replace later. However, most beginners encountering this problem really just want to build a list by adding elements to it. That should be done using the .append method, although there will often be problem-specific ways to create the list more directly. Please see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list? for details.
You cannot assign to a list like xs[i] = value, unless the list already is initialized with at least i+1 elements. Instead, use xs.append(value) to add elements to the end of the list. (Though you could use the assignment notation if you were using a dictionary instead of a list.)
Creating an empty list:
>>> xs = [None] * 10
>>> xs
[None, None, None, None, None, None, None, None, None, None]
Assigning a value to an existing element of the above list:
>>> xs[1] = 5
>>> xs
[None, 5, None, None, None, None, None, None, None, None]
Keep in mind that something like xs[15] = 5 would still fail, as our list has only 10 elements.
range(x) creates a list from [0, 1, 2, ... x-1]
# 2.X only. Use list(range(10)) in 3.X.
>>> xs = range(10)
>>> xs
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Using a function to create a list:
>>> def display():
... xs = []
... for i in range(9): # This is just to tell you how to create a list.
... xs.append(i)
... return xs
...
>>> print display()
[0, 1, 2, 3, 4, 5, 6, 7, 8]
List comprehension (Using the squares because for range you don't need to do all this, you can just return range(0,9) ):
>>> def display():
... return [x**2 for x in range(9)]
...
>>> print display()
[0, 1, 4, 9, 16, 25, 36, 49, 64]
Try this instead:
lst = [None] * 10
The above will create a list of size 10, where each position is initialized to None. After that, you can add elements to it:
lst = [None] * 10
for i in range(10):
lst[i] = i
Admittedly, that's not the Pythonic way to do things. Better do this:
lst = []
for i in range(10):
lst.append(i)
Or even simpler, in Python 2.x you can do this to initialize a list with values from 0 to 9:
lst = range(10)
And in Python 3.x:
lst = list(range(10))
varunl's currently accepted answer
>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]
Works well for non-reference types like numbers. Unfortunately if you want to create a list-of-lists you will run into referencing errors. Example in Python 2.7.6:
>>> a = [[]]*10
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>>
As you can see, each element is pointing to the same list object. To get around this, you can create a method that will initialize each position to a different object reference.
def init_list_of_objects(size):
list_of_objects = list()
for i in range(0,size):
list_of_objects.append( list() ) #different object reference each time
return list_of_objects
>>> a = init_list_of_objects(10)
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [], [], [], [], [], [], [], [], []]
>>>
There is likely a default, built-in python way of doing this (instead of writing a function), but I'm not sure what it is. Would be happy to be corrected!
Edit: It's [ [] for _ in range(10)]
Example :
>>> [ [random.random() for _ in range(2) ] for _ in range(5)]
>>> [[0.7528051908943816, 0.4325669600055032], [0.510983236521753, 0.7789949902294716], [0.09475179523690558, 0.30216475640534635], [0.3996890132468158, 0.6374322093017013], [0.3374204010027543, 0.4514925173253973]]
There are two "quick" methods:
x = length_of_your_list
a = [None]*x
# or
a = [None for _ in xrange(x)]
It appears that [None]*x is faster:
>>> from timeit import timeit
>>> timeit("[None]*100",number=10000)
0.023542165756225586
>>> timeit("[None for _ in xrange(100)]",number=10000)
0.07616496086120605
But if you are ok with a range (e.g. [0,1,2,3,...,x-1]), then range(x) might be fastest:
>>> timeit("range(100)",number=10000)
0.012513160705566406
You can .append(element) to the list, e.g.:
s1.append(i)
What you are currently trying to do is access an element (s1[i]) that does not exist.
I'm surprised nobody suggest this simple approach to creating a list of empty lists. This is an old thread, but just adding this for completeness. This will create a list of 10 empty lists
x = [[] for i in range(10)]
The accepted answer has some gotchas. For example:
>>> a = [{}] * 3
>>> a
[{}, {}, {}]
>>> a[0]['hello'] = 5
>>> a
[{'hello': 5}, {'hello': 5}, {'hello': 5}]
>>>
So each dictionary refers to the same object. Same holds true if you initialize with arrays or objects.
You could do this instead:
>>> b = [{} for i in range(0, 3)]
>>> b
[{}, {}, {}]
>>> b[0]['hello'] = 6
>>> b
[{'hello': 6}, {}, {}]
>>>
How do I create an empty list that can hold 10 elements?
All lists can hold as many elements as you like, subject only to the limit of available memory. The only "size" of a list that matters is the number of elements currently in it.
However, that gives IndexError: list assignment index out of range. Why?
The first time through the loop, i is equal to 0. Thus, we attempt xs[0] = 0. This does not work because there are currently 0 elements in the list, so 0 is not a valid index.
We cannot use indexing to write list elements that don't already exist - we can only overwrite existing ones. Instead, we should use the .append method:
xs = list();
for i in range(0, 9):
xs.append(i)
The next problem you will note is that your list will actually have only 9 elements, because the end point is skipped by the range function. (As side notes: [] works just as well as list(), the semicolon is unnecessary, and only one parameter is needed for range if you're starting from 0.) Addressing those issues gives:
xs = []
for i in range(10):
xs.append(i)
However, this is still missing the mark - range is not some magical keyword that's part of the language the way for (or, say, def) is.
In 2.x, range is a function, which directly returns the list that we already wanted:
xs = range(10) # 2.x specific!
# In 3.x, we don't get a list; we can do a lot of things with the
# result, but we can't e.g. append or replace elements.
In 3.x, range is a cleverly designed class, and range(10) creates an instance. To get the desired list, we can simply feed it to the list constructor:
xs = list(range(10)) # correct in 3.x, redundant in 2.x
One simple way to create a 2D matrix of size n using nested list comprehensions:
m = [[None for _ in range(n)] for _ in range(n)]
I'm a bit surprised that the easiest way to create an initialised list is not in any of these answers. Just use a generator in the list function:
list(range(9))
Another option is to use numpy for fixed size arrays (of pointers):
> pip install numpy
import numpy as np
a = np.empty(10, dtype=np.object)
a[1] = 2
a[5] = "john"
a[3] = []
If you just want numbers, you can do with numpy:
a = np.arange(10)
Here's my code for 2D list in python which would read no. of rows from the input :
empty = []
row = int(input())
for i in range(row):
temp = list(map(int, input().split()))
empty.append(temp)
for i in empty:
for j in i:
print(j, end=' ')
print('')
A list is always "iterable" and you can always add new elements to it:
insert: list.insert(indexPosition, value)
append: list.append(value)
extend: list.extend(value)
In your case, you had instantiated an empty list of length 0. Therefore, when you try to add any value to the list using the list index (i), it is referring to a location that does not exist. Therefore, you were getting the error "IndexError: list assignment index out of range".
You can try this instead:
s1 = list();
for i in range(0,9):
s1.append(i)
print (s1)
To create a list of size 10(let's say), you can first create an empty array, like np.empty(10) and then convert it to list using arrayName.tolist(). Alternately, you can chain them as well.
**`np.empty(10).tolist()`**
I came across this SO question while searching for a similar problem. I had to build a 2D array and then replace some elements of each list (in 2D array) with elements from a dict.
I then came across this SO question which helped me, maybe this will help other beginners to get around.
The key trick was to initialize the 2D array as an numpy array and then using array[i,j] instead of array[i][j].
For reference this is the piece of code where I had to use this :
nd_array = []
for i in range(30):
nd_array.append(np.zeros(shape = (32,1)))
new_array = []
for i in range(len(lines)):
new_array.append(nd_array)
new_array = np.asarray(new_array)
for i in range(len(lines)):
splits = lines[i].split(' ')
for j in range(len(splits)):
#print(new_array[i][j])
new_array[i,j] = final_embeddings[dictionary[str(splits[j])]-1].reshape(32,1)
Now I know we can use list comprehension but for simplicity sake I am using a nested for loop. Hope this helps others who come across this post.
Not technically a list but similar to a list in terms of functionality and it's a fixed length
from collections import deque
my_deque_size_10 = deque(maxlen=10)
If it's full, ie got 10 items then adding another item results in item #index 0 being discarded. FIFO..but you can also append in either direction.
Used in say
a rolling average of stats
piping a list through it aka sliding a window over a list until you get a match against another deque object.
If you need a list then when full just use list(deque object)
s1 = []
for i in range(11):
s1.append(i)
print s1
To create a list, just use these brackets: "[]"
To add something to a list, use list.append()
Make it more reusable as a function.
def createEmptyList(length,fill=None):
'''
return a (empty) list of a given length
Example:
print createEmptyList(3,-1)
>> [-1, -1, -1]
print createEmptyList(4)
>> [None, None, None, None]
'''
return [fill] * length
This code generates an array that contains 10 random numbers.
import random
numrand=[]
for i in range(0,10):
a = random.randint(1,50)
numrand.append(a)
print(a,i)
print(numrand)

Issue while appending item in list in a list in python

I think similar questions exist but I can't seem to find them out
x=list(([],)*3)
x[0].append(1)
x[1].append(2)
x[2].append(3)
print(x)
I want the result to look like this:
[[1],[2],[3]]
But instead, I get:
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Also I really don't want to use any loops but if it is necessary then I'll try
Just realized you don't want to use a for loop.
Option 1: no for loops:
x = []
x.append([1])
x.append([2])
x.append([3])
print(x)
> [[1], [2], [3]]
Option 2: using loops.
Easiest and cleanest way is to use list comprehension like this:
x = [[i] for i in range(1,4)]
print(x)
> [[1], [2], [3]]
Or you can use a plain for loop and create an empty list before:
result = []
for i in range(1,4):
result.append([i])
result
Instead of the first line, use
x = [[] for _ in range(3)]
In the current code, x is a list of the empty lists which are actually the same object. That's how [...] * n works; it repeats the same objects n times. So appending an item to one of these empty lists would append the item to the others, because they are the same.
You can create an empty list first and starts appending each element as a list.
x=[]
x.append([1])
x.append([2])
x.append([3])
print(x)

how to add certain numbers to a list in a python list?

a = [[1,2,3], [4,5,6]]
I want to add 2 and 5. How do I add up only the numbers 2 and 5 in the list?
I tried this way but getting an error:
x = [[1,2,3], [4,5,6]]
for i in range(len(x)):
print(sum(x[i][1]))
Create a new variable and assign 0 to it. Then in for loop instead of print(sum(x[i][1])) do my_variable += x[i][1].
Try this:
x = [[1,2,3], [4,5,6]]
new_list = [i[1] for i in x]
The result(new_list) will be
[2, 5]
Then you can do whatever you want with your new list.
To use sum() function you need multiple elements. Because one element can't iterate.
x = [[1, 2, 3], [4, 5, 6]]
print(sum(i[1] for i in x))
# Output
# 7
Lets understand why you are getting an error. If I remove the sum(), you can see that x[i][1] returns an integer. This means that when you use sum(integer), it doesn't make sense.
x = [[1,2,3], [4,5,6]]
for i in range(len(x)):
print(x[i][1])
#2
#5
You would want to add the 2 numbers to a dummy variable using += to maintain the sum.
s = 0
x = [[1,2,3], [4,5,6]]
for i in range(len(x)):
s+=x[i][1]
print(s)
#7
Finally, if you don't want to use += you can always fetch the 2 elements and sum them later. Here I use a list comprehension for this.
sum([i[1] for i in x])
#7
This is the same as -
l = []
x = [[1,2,3], [4,5,6]]
for i in range(len(x)):
l.append(x[i][1])
print(sum(l))
#7

Elegant way to work with 2D list in python

I have just start with Python 2.7 for few months. I usually work with some 2D list in Python, simple task but I wonder that is there some more elegant way to do the same my job in Python 2.7?
Here is my task. I have a 2D list:
my_list = [["__cat_1", "__cat_2"],
["__cat_3", "__cat_4"]]
I want to convert the above 2D string list to 2D integer list.
expected_result = [[1, 2], [3, 4]]
As usual, I do as the following:
def convert_2D_string_list(my_list):
for a_group in my_list:
yield [int(k.replace("__cat_","")) for k in a_group]
But the above could not work when my input has 3 dimensions like:
my_second_list = [[["__cat_1", "__cat_2"], "__cat_12"],
[["__cat_3", "__cat_4"], "__cat_34"]]
If my input list is integer, I know the elegant way to convert for transform it. For example:
def convert_2D_int_list:
my_list = [[1, 2], [3, 4]]
import numpy as np
# Assume that, I want to add 1 for each of element
# Convert to numpy array
my_list = np.asarray(my_list)
my_list += 1
# my_list = [[2, 3], [4, 5]]
return my_list
What is the best practice for my convert_2D_string_list method?
So in case of it is not 2D list, but 3D list -> I will not afraid about the number of dimensions.
Any suggestion would be appreciated.
Thank you.
Numpy array works very well with NUMbers, it's a little more tricky with strings. np.vectorize is a work around for such situation, even no performance improvement is done. But it manages any number of dimensions, hope you will find it elegant.
a=np.array([[[['__cat_0', '__cat_1'],
['__cat_2', '__cat_3']],
[['__cat_4', '__cat_5'],
['__cat_6', '__cat_7']]],
[[['__cat_8', '__cat_9'],
['__cat_10', '__cat_11']],
[['__cat_12', '__cat_13'],
['__cat_14', '__cat_15']]]])
def f(str): return int(str[6:])
fv=np.vectorize(f)
print(fv(a))
gives :
[[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]]
[[[ 8 9]
[10 11]]
[[12 13]
[14 15]]]]
Remark : a is np.vectorize(lambda n : '__cat_'+str(n))(np.arange(16).reshape((2,)*4)) ;)
Modify the values whilst recursively copying the list(s).
def visit(fn, xs):
return [visit(fn, x) if isinstance(x, list) else fn(x) for x in xs]
in this case the modification function fn is something like:
def categorize(s):
return int(re.match(r'__cat_(\d*)', s).group(1))
testing this:
my_second_list = [[["__cat_1", "__cat_2"], "__cat_12"],
[["__cat_3", "__cat_4"], "__cat_34"]]
print visit(categorize, my_second_list)
outputs:
> [[[1, 2], 12], [[3, 4], 34]]
I hope this may useful for you:
def con(x):
# you can do here whatever u want
return x.split('_')[-1]
y= [con(v) for v in my_list]
You can convert your string 2D list to int 2D list using map and list comprehensions
my_list = [["__cat_1", "__cat_2"],["__cat_3", "__cat_4"]]
my_list = [map(lambda z: int(z.split('_')[-1]), ls) for ls in my_list]
print my_list # [[1,2],[3,4]]
3d list:
my_list = [["__cat_1", "__cat_2", '__cat_3'],["__cat_1", "__cat_2", '__cat_3']]
my_list = [map(lambda z: int(z.split('_')[-1]), ls) for ls in my_list]
print my_list # [[1,2,3],[1,2,3],[1,2,3]]

Categories